From d5d214b79f952beef771f898a2b47ab5cfcddedc Mon Sep 17 00:00:00 2001 From: John Marino Date: Sun, 28 Aug 2016 02:05:50 +0200 Subject: [PATCH] Update gcc-50 to SVN version 239798 (gcc-5-branch) This is equivalent to the gcc 5.4 release + 3 months Last Changed Date: 2016-08-27 02:16:05 +0200 (Sat, 27 Aug 2016) --- contrib/gcc-5.0/LAST_UPDATED | 4 +- contrib/gcc-5.0/gcc/BASE-VER | 2 +- contrib/gcc-5.0/gcc/DATESTAMP | 2 +- contrib/gcc-5.0/gcc/alias.c | 40 +- contrib/gcc-5.0/gcc/bb-reorder.c | 37 +- contrib/gcc-5.0/gcc/builtins.c | 106 ++++- contrib/gcc-5.0/gcc/c-family/c-common.c | 2 +- contrib/gcc-5.0/gcc/c-family/c-common.h | 2 +- contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c | 1 + contrib/gcc-5.0/gcc/c-family/c-gimplify.c | 12 +- contrib/gcc-5.0/gcc/c-family/c-ppoutput.c | 38 +- contrib/gcc-5.0/gcc/c-family/c-pragma.c | 9 +- contrib/gcc-5.0/gcc/c/c-decl.c | 96 ++++- contrib/gcc-5.0/gcc/c/c-parser.c | 18 +- contrib/gcc-5.0/gcc/c/c-tree.h | 1 + contrib/gcc-5.0/gcc/c/c-typeck.c | 121 ++++-- contrib/gcc-5.0/gcc/calls.c | 20 +- contrib/gcc-5.0/gcc/cfgexpand.c | 9 +- contrib/gcc-5.0/gcc/cgraph.c | 7 +- contrib/gcc-5.0/gcc/cgraph.h | 2 +- contrib/gcc-5.0/gcc/cgraphclones.c | 1 + contrib/gcc-5.0/gcc/cgraphunit.c | 1 + contrib/gcc-5.0/gcc/combine.c | 35 +- contrib/gcc-5.0/gcc/common.opt | 2 +- .../gcc-5.0/gcc/config/i386/avx512bwintrin.h | 44 +-- .../gcc-5.0/gcc/config/i386/avx512dqintrin.h | 39 +- .../gcc-5.0/gcc/config/i386/avx512fintrin.h | 261 +++++++------ .../gcc/config/i386/avx512ifmaintrin.h | 4 +- .../gcc/config/i386/avx512ifmavlintrin.h | 8 +- .../gcc/config/i386/avx512vbmiintrin.h | 7 +- .../gcc/config/i386/avx512vbmivlintrin.h | 6 +- .../gcc/config/i386/avx512vlbwintrin.h | 70 ++-- .../gcc/config/i386/avx512vldqintrin.h | 27 +- .../gcc-5.0/gcc/config/i386/avx512vlintrin.h | 97 ++--- .../gcc-5.0/gcc/config/i386/constraints.md | 15 +- contrib/gcc-5.0/gcc/config/i386/driver-i386.c | 73 ++-- contrib/gcc-5.0/gcc/config/i386/i386.c | 222 +++++++---- contrib/gcc-5.0/gcc/config/i386/i386.h | 2 + contrib/gcc-5.0/gcc/config/i386/i386.md | 39 +- contrib/gcc-5.0/gcc/config/i386/sse.md | 344 ++++++---------- contrib/gcc-5.0/gcc/cp/call.c | 33 +- contrib/gcc-5.0/gcc/cp/cfns.gperf | 10 +- contrib/gcc-5.0/gcc/cp/cfns.h | 41 +- contrib/gcc-5.0/gcc/cp/class.c | 4 +- contrib/gcc-5.0/gcc/cp/constexpr.c | 353 ++++++++++++----- contrib/gcc-5.0/gcc/cp/cp-tree.h | 3 +- contrib/gcc-5.0/gcc/cp/cvt.c | 2 +- contrib/gcc-5.0/gcc/cp/decl.c | 76 +++- contrib/gcc-5.0/gcc/cp/decl2.c | 15 +- contrib/gcc-5.0/gcc/cp/except.c | 3 +- contrib/gcc-5.0/gcc/cp/init.c | 7 +- contrib/gcc-5.0/gcc/cp/method.c | 36 +- contrib/gcc-5.0/gcc/cp/optimize.c | 2 + contrib/gcc-5.0/gcc/cp/parser.c | 56 ++- contrib/gcc-5.0/gcc/cp/pt.c | 176 ++++++--- contrib/gcc-5.0/gcc/cp/rtti.c | 10 +- contrib/gcc-5.0/gcc/cp/semantics.c | 16 +- contrib/gcc-5.0/gcc/cp/tree.c | 19 +- contrib/gcc-5.0/gcc/cp/typeck.c | 35 +- contrib/gcc-5.0/gcc/cp/typeck2.c | 30 +- contrib/gcc-5.0/gcc/dse.c | 23 +- contrib/gcc-5.0/gcc/dwarf2out.c | 20 +- contrib/gcc-5.0/gcc/emit-rtl.c | 3 +- contrib/gcc-5.0/gcc/explow.c | 36 +- contrib/gcc-5.0/gcc/expr.c | 7 + contrib/gcc-5.0/gcc/fold-const.c | 198 ++++++---- contrib/gcc-5.0/gcc/fwprop.c | 32 +- contrib/gcc-5.0/gcc/gcc.c | 5 +- contrib/gcc-5.0/gcc/gcse.c | 27 +- contrib/gcc-5.0/gcc/genpreds.c | 110 +++++- contrib/gcc-5.0/gcc/gimple-expr.c | 9 +- contrib/gcc-5.0/gcc/gimple-expr.h | 10 +- contrib/gcc-5.0/gcc/gimple-fold.c | 16 +- .../gcc/gimple-ssa-strength-reduction.c | 12 +- contrib/gcc-5.0/gcc/gimple.c | 9 +- contrib/gcc-5.0/gcc/gimplify.c | 38 +- contrib/gcc-5.0/gcc/haifa-sched.c | 6 +- contrib/gcc-5.0/gcc/ifcvt.c | 48 +-- contrib/gcc-5.0/gcc/ipa-cp.c | 25 +- contrib/gcc-5.0/gcc/ipa-devirt.c | 1 + contrib/gcc-5.0/gcc/ipa-icf.c | 7 +- contrib/gcc-5.0/gcc/ipa-inline-analysis.c | 127 +++--- contrib/gcc-5.0/gcc/ipa-inline.h | 2 + contrib/gcc-5.0/gcc/ipa-polymorphic-call.c | 4 +- contrib/gcc-5.0/gcc/ipa-prop.c | 6 +- contrib/gcc-5.0/gcc/ipa-pure-const.c | 17 +- contrib/gcc-5.0/gcc/ipa-split.c | 66 +++- contrib/gcc-5.0/gcc/ira-build.c | 2 +- contrib/gcc-5.0/gcc/ira.c | 105 +++-- contrib/gcc-5.0/gcc/lra-constraints.c | 26 +- contrib/gcc-5.0/gcc/lra-remat.c | 194 +++++---- contrib/gcc-5.0/gcc/lra.c | 11 +- contrib/gcc-5.0/gcc/lto-streamer.h | 2 +- contrib/gcc-5.0/gcc/lto/lto-partition.c | 4 +- contrib/gcc-5.0/gcc/match.pd | 14 +- contrib/gcc-5.0/gcc/modulo-sched.c | 7 +- contrib/gcc-5.0/gcc/omp-low.c | 11 +- contrib/gcc-5.0/gcc/optabs.c | 23 +- contrib/gcc-5.0/gcc/passes.c | 9 +- contrib/gcc-5.0/gcc/postreload.c | 18 +- contrib/gcc-5.0/gcc/regstat.c | 2 +- contrib/gcc-5.0/gcc/rtl.h | 4 + contrib/gcc-5.0/gcc/rtlanal.c | 2 +- contrib/gcc-5.0/gcc/sched-deps.c | 28 +- contrib/gcc-5.0/gcc/sched-int.h | 1 + contrib/gcc-5.0/gcc/sel-sched-ir.c | 51 ++- contrib/gcc-5.0/gcc/sel-sched.c | 59 +-- contrib/gcc-5.0/gcc/shrink-wrap.c | 40 +- contrib/gcc-5.0/gcc/simplify-rtx.c | 18 +- contrib/gcc-5.0/gcc/stmt.c | 16 +- contrib/gcc-5.0/gcc/targhooks.c | 8 +- contrib/gcc-5.0/gcc/tree-cfg.c | 4 +- contrib/gcc-5.0/gcc/tree-chrec.c | 22 +- contrib/gcc-5.0/gcc/tree-data-ref.c | 21 +- contrib/gcc-5.0/gcc/tree-inline.c | 7 +- contrib/gcc-5.0/gcc/tree-nested.c | 2 +- contrib/gcc-5.0/gcc/tree-parloops.c | 1 + contrib/gcc-5.0/gcc/tree-predcom.c | 8 +- contrib/gcc-5.0/gcc/tree-scalar-evolution.c | 70 +++- contrib/gcc-5.0/gcc/tree-sra.c | 10 +- contrib/gcc-5.0/gcc/tree-ssa-alias.c | 22 +- contrib/gcc-5.0/gcc/tree-ssa-dom.c | 9 +- contrib/gcc-5.0/gcc/tree-ssa-forwprop.c | 2 +- contrib/gcc-5.0/gcc/tree-ssa-loop-ivcanon.c | 40 +- contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c | 18 +- contrib/gcc-5.0/gcc/tree-ssa-loop.c | 6 +- contrib/gcc-5.0/gcc/tree-ssa-math-opts.c | 20 +- contrib/gcc-5.0/gcc/tree-ssa-pre.c | 106 ++--- contrib/gcc-5.0/gcc/tree-ssa-reassoc.c | 58 ++- contrib/gcc-5.0/gcc/tree-ssa-sccvn.c | 15 +- contrib/gcc-5.0/gcc/tree-ssa-sccvn.h | 2 +- contrib/gcc-5.0/gcc/tree-ssa-strlen.c | 65 ++- contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c | 21 +- contrib/gcc-5.0/gcc/tree-ssa-uninit.c | 43 +- contrib/gcc-5.0/gcc/tree-ssa.c | 15 +- contrib/gcc-5.0/gcc/tree-vect-data-refs.c | 77 ++-- contrib/gcc-5.0/gcc/tree-vect-loop.c | 38 +- contrib/gcc-5.0/gcc/tree-vrp.c | 7 +- contrib/gcc-5.0/gcc/tree.c | 11 +- contrib/gcc-5.0/gcc/ubsan.c | 1 + contrib/gcc-5.0/gcc/var-tracking.c | 5 - contrib/gcc-5.0/gcc/varasm.c | 32 +- contrib/gcc-5.0/gcc/wide-int.cc | 72 ++-- contrib/gcc-5.0/gcc/wide-int.h | 4 +- contrib/gcc-5.0/include/demangle.h | 4 + contrib/gcc-5.0/libbacktrace/elf.c | 3 + contrib/gcc-5.0/libcpp/files.c | 5 +- contrib/gcc-5.0/libcpp/include/cpplib.h | 1 + contrib/gcc-5.0/libcpp/line-map.c | 2 +- contrib/gcc-5.0/libcpp/macro.c | 9 + contrib/gcc-5.0/libgcc/config.host | 9 +- contrib/gcc-5.0/libgcc/libgcc2.c | 7 +- contrib/gcc-5.0/libgomp/oacc-mem.c | 6 +- contrib/gcc-5.0/libiberty/cp-demangle.c | 101 +++-- contrib/gcc-5.0/libiberty/cp-demint.c | 1 + contrib/gcc-5.0/libiberty/cplus-dem.c | 22 ++ contrib/gcc-5.0/libitm/ChangeLog | 8 + .../config/cpu/aarch64/atomic_word.h | 44 --- .../libstdc++-v3/include/backward/strstream | 5 +- .../libstdc++-v3/include/bits/alloc_traits.h | 126 +++++- .../libstdc++-v3/include/bits/basic_string.h | 101 ++++- .../include/bits/basic_string.tcc | 10 +- .../libstdc++-v3/include/bits/c++0x_warning.h | 6 +- .../libstdc++-v3/include/bits/c++config | 2 +- .../libstdc++-v3/include/bits/forward_list.h | 5 +- .../include/bits/locale_facets_nonio.h | 2 +- .../libstdc++-v3/include/bits/random.h | 168 +------- .../libstdc++-v3/include/bits/random.tcc | 152 -------- .../include/bits/regex_executor.tcc | 5 +- .../libstdc++-v3/include/bits/regex_scanner.h | 15 +- .../include/bits/regex_scanner.tcc | 10 +- .../libstdc++-v3/include/bits/shared_ptr.h | 22 +- .../include/bits/shared_ptr_base.h | 22 +- .../libstdc++-v3/include/bits/stl_algo.h | 2 +- .../libstdc++-v3/include/bits/stl_algobase.h | 12 +- .../libstdc++-v3/include/bits/stl_iterator.h | 7 + .../libstdc++-v3/include/bits/stl_tree.h | 63 ++- .../include/bits/uniform_int_dist.h | 369 ++++++++++++++++++ .../include/bits/valarray_before.h | 14 +- .../libstdc++-v3/include/c_global/cmath | 6 +- .../gcc-5.0/libstdc++-v3/include/debug/string | 53 ++- .../gcc-5.0/libstdc++-v3/include/debug/vector | 9 +- .../include/experimental/fs_dir.h | 59 ++- .../include/experimental/fs_fwd.h | 49 +-- .../include/experimental/fs_ops.h | 5 +- .../include/experimental/fs_path.h | 20 +- .../include/experimental/optional | 6 + .../include/experimental/string_view | 2 +- .../include/experimental/string_view.tcc | 2 +- .../libstdc++-v3/include/experimental/tuple | 4 +- .../pb_ds/detail/bin_search_tree_/traits.hpp | 9 +- .../gcc-5.0/libstdc++-v3/include/std/bitset | 4 +- .../libstdc++-v3/include/std/functional | 36 +- .../gcc-5.0/libstdc++-v3/include/std/mutex | 23 +- .../libstdc++-v3/include/tr2/dynamic_bitset | 3 + .../gcc-5.0/libstdc++-v3/src/c++11/codecvt.cc | 8 +- .../gcc-5.0/libstdc++-v3/src/c++11/futex.cc | 2 +- .../gcc-5.0/libstdc++-v3/src/c++11/thread.cc | 6 +- 198 files changed, 4363 insertions(+), 2389 deletions(-) delete mode 100644 contrib/gcc-5.0/libstdc++-v3/config/cpu/aarch64/atomic_word.h create mode 100644 contrib/gcc-5.0/libstdc++-v3/include/bits/uniform_int_dist.h diff --git a/contrib/gcc-5.0/LAST_UPDATED b/contrib/gcc-5.0/LAST_UPDATED index fceaaa2240..719cb85bfd 100644 --- a/contrib/gcc-5.0/LAST_UPDATED +++ b/contrib/gcc-5.0/LAST_UPDATED @@ -1,2 +1,2 @@ -231244:231263 -Last Changed Date: 2015-12-04 01:16:08 +0100 (Fri, 04 Dec 2015) +239798 +Last Changed Date: 2016-08-27 02:16:05 +0200 (Sat, 27 Aug 2016) diff --git a/contrib/gcc-5.0/gcc/BASE-VER b/contrib/gcc-5.0/gcc/BASE-VER index c7cb1311a6..ade65226e0 100644 --- a/contrib/gcc-5.0/gcc/BASE-VER +++ b/contrib/gcc-5.0/gcc/BASE-VER @@ -1 +1 @@ -5.3.1 +5.4.1 diff --git a/contrib/gcc-5.0/gcc/DATESTAMP b/contrib/gcc-5.0/gcc/DATESTAMP index afb984d5f6..ece9e30291 100644 --- a/contrib/gcc-5.0/gcc/DATESTAMP +++ b/contrib/gcc-5.0/gcc/DATESTAMP @@ -1 +1 @@ -20151204 +20160827 diff --git a/contrib/gcc-5.0/gcc/alias.c b/contrib/gcc-5.0/gcc/alias.c index d85830ef5c..6949a157d4 100644 --- a/contrib/gcc-5.0/gcc/alias.c +++ b/contrib/gcc-5.0/gcc/alias.c @@ -1880,7 +1880,7 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base, } /* Return TRUE if EXPR refers to a VALUE whose uid is greater than - that of V. */ + (or equal to) that of V. */ static bool refs_newer_value_p (const_rtx expr, rtx v) @@ -1888,14 +1888,14 @@ refs_newer_value_p (const_rtx expr, rtx v) int minuid = CSELIB_VAL_PTR (v)->uid; subrtx_iterator::array_type array; FOR_EACH_SUBRTX (iter, array, expr, NONCONST) - if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid > minuid) + if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid >= minuid) return true; return false; } /* Convert the address X into something we can use. This is done by returning - it unchanged unless it is a value; in the latter case we call cselib to get - a more useful rtx. */ + it unchanged unless it is a VALUE or VALUE +/- constant; for VALUE + we call cselib to get a more useful rtx. */ rtx get_addr (rtx x) @@ -1904,7 +1904,23 @@ get_addr (rtx x) struct elt_loc_list *l; if (GET_CODE (x) != VALUE) - return x; + { + if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS) + && GET_CODE (XEXP (x, 0)) == VALUE + && CONST_SCALAR_INT_P (XEXP (x, 1))) + { + rtx op0 = get_addr (XEXP (x, 0)); + if (op0 != XEXP (x, 0)) + { + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 1)) == CONST_INT) + return plus_constant (GET_MODE (x), op0, INTVAL (XEXP (x, 1))); + return simplify_gen_binary (GET_CODE (x), GET_MODE (x), + op0, XEXP (x, 1)); + } + } + return x; + } v = CSELIB_VAL_PTR (x); if (v) { @@ -2684,6 +2700,20 @@ output_dependence (const_rtx mem, const_rtx x) /*mem_canonicalized=*/false, /*x_canonicalized*/false, /*writep=*/true); } + +/* Likewise, but we already have a canonicalized MEM, and X_ADDR for X. + Also, consider X in X_MODE (which might be from an enclosing + STRICT_LOW_PART / ZERO_EXTRACT). + If MEM_CANONICALIZED is true, MEM is canonicalized. */ + +int +canon_output_dependence (const_rtx mem, bool mem_canonicalized, + const_rtx x, machine_mode x_mode, rtx x_addr) +{ + return write_dependence_p (mem, x, x_mode, x_addr, + mem_canonicalized, /*x_canonicalized=*/true, + /*writep=*/true); +} diff --git a/contrib/gcc-5.0/gcc/bb-reorder.c b/contrib/gcc-5.0/gcc/bb-reorder.c index c2a3be3255..7d5073b024 100644 --- a/contrib/gcc-5.0/gcc/bb-reorder.c +++ b/contrib/gcc-5.0/gcc/bb-reorder.c @@ -187,6 +187,10 @@ typedef struct bbro_basic_block_data_def /* Which trace was this bb visited in? */ int visited; + /* Cached maximum frequency of interesting incoming edges. + Minus one means not yet computed. */ + int priority; + /* Which heap is BB in (if any)? */ bb_heap_t *heap; @@ -805,7 +809,15 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th, while (best_edge); trace->last = bb; bbd[trace->first->index].start_of_trace = *n_traces - 1; - bbd[trace->last->index].end_of_trace = *n_traces - 1; + if (bbd[trace->last->index].end_of_trace != *n_traces - 1) + { + bbd[trace->last->index].end_of_trace = *n_traces - 1; + /* Update the cached maximum frequency for interesting predecessor + edges for successors of the new trace end. */ + FOR_EACH_EDGE (e, ei, trace->last->succs) + if (EDGE_FREQUENCY (e) > bbd[e->dest->index].priority) + bbd[e->dest->index].priority = EDGE_FREQUENCY (e); + } /* The trace is terminated so we have to recount the keys in heap (some block can have a lower key because now one of its predecessors @@ -875,6 +887,7 @@ copy_bb (basic_block old_bb, edge e, basic_block bb, int trace) bbd[i].end_of_trace = -1; bbd[i].in_trace = -1; bbd[i].visited = 0; + bbd[i].priority = -1; bbd[i].heap = NULL; bbd[i].node = NULL; } @@ -905,7 +918,6 @@ bb_to_key (basic_block bb) { edge e; edge_iterator ei; - int priority = 0; /* Use index as key to align with its original order. */ if (optimize_function_for_size_p (cfun)) @@ -919,17 +931,23 @@ bb_to_key (basic_block bb) /* Prefer blocks whose predecessor is an end of some trace or whose predecessor edge is EDGE_DFS_BACK. */ - FOR_EACH_EDGE (e, ei, bb->preds) + int priority = bbd[bb->index].priority; + if (priority == -1) { - if ((e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) - && bbd[e->src->index].end_of_trace >= 0) - || (e->flags & EDGE_DFS_BACK)) + priority = 0; + FOR_EACH_EDGE (e, ei, bb->preds) { - int edge_freq = EDGE_FREQUENCY (e); + if ((e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) + && bbd[e->src->index].end_of_trace >= 0) + || (e->flags & EDGE_DFS_BACK)) + { + int edge_freq = EDGE_FREQUENCY (e); - if (edge_freq > priority) - priority = edge_freq; + if (edge_freq > priority) + priority = edge_freq; + } } + bbd[bb->index].priority = priority; } if (priority) @@ -2283,6 +2301,7 @@ reorder_basic_blocks (void) bbd[i].end_of_trace = -1; bbd[i].in_trace = -1; bbd[i].visited = 0; + bbd[i].priority = -1; bbd[i].heap = NULL; bbd[i].node = NULL; } diff --git a/contrib/gcc-5.0/gcc/builtins.c b/contrib/gcc-5.0/gcc/builtins.c index 137001522e..f6a7f21da4 100644 --- a/contrib/gcc-5.0/gcc/builtins.c +++ b/contrib/gcc-5.0/gcc/builtins.c @@ -497,8 +497,12 @@ get_pointer_alignment_1 (tree exp, unsigned int *alignp, { *bitposp = ptr_misalign * BITS_PER_UNIT; *alignp = ptr_align * BITS_PER_UNIT; + /* Make sure to return a sensible alignment when the multiplication + by BITS_PER_UNIT overflowed. */ + if (*alignp == 0) + *alignp = 1u << (HOST_BITS_PER_INT - 1); /* We cannot really tell whether this result is an approximation. */ - return true; + return false; } else { @@ -9554,6 +9558,8 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) mode = TYPE_MODE (TREE_TYPE (arg)); + bool is_ibm_extended = MODE_COMPOSITE_P (mode); + /* If there is no optab, try generic code. */ switch (DECL_FUNCTION_CODE (fndecl)) { @@ -9563,10 +9569,18 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) { /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */ tree const isgr_fn = builtin_decl_explicit (BUILT_IN_ISGREATER); - tree const type = TREE_TYPE (arg); + tree type = TREE_TYPE (arg); REAL_VALUE_TYPE r; char buf[128]; + if (is_ibm_extended) + { + /* NaN and Inf are encoded in the high-order double value + only. The low-order value is not significant. */ + type = double_type_node; + mode = DFmode; + arg = fold_build1_loc (loc, NOP_EXPR, type, arg); + } get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); real_from_string (&r, buf); result = build_call_expr (isgr_fn, 2, @@ -9579,10 +9593,18 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) { /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */ tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL); - tree const type = TREE_TYPE (arg); + tree type = TREE_TYPE (arg); REAL_VALUE_TYPE r; char buf[128]; + if (is_ibm_extended) + { + /* NaN and Inf are encoded in the high-order double value + only. The low-order value is not significant. */ + type = double_type_node; + mode = DFmode; + arg = fold_build1_loc (loc, NOP_EXPR, type, arg); + } get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); real_from_string (&r, buf); result = build_call_expr (isle_fn, 2, @@ -9602,21 +9624,72 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg) /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) & islessequal(fabs(x),DBL_MAX). */ tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL); - tree const isge_fn = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL); - tree const type = TREE_TYPE (arg); + tree type = TREE_TYPE (arg); + tree orig_arg, max_exp, min_exp; + machine_mode orig_mode = mode; REAL_VALUE_TYPE rmax, rmin; char buf[128]; + orig_arg = arg = builtin_save_expr (arg); + if (is_ibm_extended) + { + /* Use double to test the normal range of IBM extended + precision. Emin for IBM extended precision is + different to emin for IEEE double, being 53 higher + since the low double exponent is at least 53 lower + than the high double exponent. */ + type = double_type_node; + mode = DFmode; + arg = fold_build1_loc (loc, NOP_EXPR, type, arg); + } + arg = fold_build1_loc (loc, ABS_EXPR, type, arg); + get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf)); real_from_string (&rmax, buf); - sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); + sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (orig_mode)->emin - 1); real_from_string (&rmin, buf); - arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg)); - result = build_call_expr (isle_fn, 2, arg, - build_real (type, rmax)); - result = fold_build2 (BIT_AND_EXPR, integer_type_node, result, - build_call_expr (isge_fn, 2, arg, - build_real (type, rmin))); + max_exp = build_real (type, rmax); + min_exp = build_real (type, rmin); + + max_exp = build_call_expr (isle_fn, 2, arg, max_exp); + if (is_ibm_extended) + { + /* Testing the high end of the range is done just using + the high double, using the same test as isfinite(). + For the subnormal end of the range we first test the + high double, then if its magnitude is equal to the + limit of 0x1p-969, we test whether the low double is + non-zero and opposite sign to the high double. */ + tree const islt_fn = builtin_decl_explicit (BUILT_IN_ISLESS); + tree const isgt_fn = builtin_decl_explicit (BUILT_IN_ISGREATER); + tree gt_min = build_call_expr (isgt_fn, 2, arg, min_exp); + tree eq_min = fold_build2 (EQ_EXPR, integer_type_node, + arg, min_exp); + tree as_complex = build1 (VIEW_CONVERT_EXPR, + complex_double_type_node, orig_arg); + tree hi_dbl = build1 (REALPART_EXPR, type, as_complex); + tree lo_dbl = build1 (IMAGPART_EXPR, type, as_complex); + tree zero = build_real (type, dconst0); + tree hilt = build_call_expr (islt_fn, 2, hi_dbl, zero); + tree lolt = build_call_expr (islt_fn, 2, lo_dbl, zero); + tree logt = build_call_expr (isgt_fn, 2, lo_dbl, zero); + tree ok_lo = fold_build1 (TRUTH_NOT_EXPR, integer_type_node, + fold_build3 (COND_EXPR, + integer_type_node, + hilt, logt, lolt)); + eq_min = fold_build2 (TRUTH_ANDIF_EXPR, integer_type_node, + eq_min, ok_lo); + min_exp = fold_build2 (TRUTH_ORIF_EXPR, integer_type_node, + gt_min, eq_min); + } + else + { + tree const isge_fn + = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL); + min_exp = build_call_expr (isge_fn, 2, arg, min_exp); + } + result = fold_build2 (BIT_AND_EXPR, integer_type_node, + max_exp, min_exp); return result; } default: @@ -9711,6 +9784,15 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index) return real_isnan (&r) ? integer_one_node : integer_zero_node; } + { + bool is_ibm_extended = MODE_COMPOSITE_P (TYPE_MODE (TREE_TYPE (arg))); + if (is_ibm_extended) + { + /* NaN and Inf are encoded in the high-order double value + only. The low-order value is not significant. */ + arg = fold_build1_loc (loc, NOP_EXPR, double_type_node, arg); + } + } arg = builtin_save_expr (arg); return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg); diff --git a/contrib/gcc-5.0/gcc/c-family/c-common.c b/contrib/gcc-5.0/gcc/c-family/c-common.c index 117f89c023..1bf5d08003 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-common.c +++ b/contrib/gcc-5.0/gcc/c-family/c-common.c @@ -10511,7 +10511,7 @@ sync_resolve_size (tree function, vec *params) tree type; int size; - if (!params) + if (vec_safe_is_empty (params)) { error ("too few arguments to function %qE", function); return 0; diff --git a/contrib/gcc-5.0/gcc/c-family/c-common.h b/contrib/gcc-5.0/gcc/c-family/c-common.h index cabf452ca1..fdb227f85c 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-common.h +++ b/contrib/gcc-5.0/gcc/c-family/c-common.h @@ -850,7 +850,7 @@ extern tree pointer_int_sum (location_t, enum tree_code, tree, tree, bool = true); /* Add qualifiers to a type, in the fashion for C. */ -extern tree c_build_qualified_type (tree, int); +extern tree c_build_qualified_type (tree, int, tree = NULL_TREE, size_t = 0); /* Build tree nodes and builtin functions common to both C and C++ language frontends. */ diff --git a/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c b/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c index 60c2d7f386..2ab7727b6b 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c +++ b/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c @@ -856,6 +856,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_decltype=200707"); cpp_define (pfile, "__cpp_attributes=200809"); cpp_define (pfile, "__cpp_rvalue_reference=200610"); + cpp_define (pfile, "__cpp_rvalue_references=200610"); cpp_define (pfile, "__cpp_variadic_templates=200704"); cpp_define (pfile, "__cpp_initializer_lists=200806"); cpp_define (pfile, "__cpp_delegating_constructors=200604"); diff --git a/contrib/gcc-5.0/gcc/c-family/c-gimplify.c b/contrib/gcc-5.0/gcc/c-family/c-gimplify.c index 4e7a96f2be..c6a67a1a44 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-gimplify.c +++ b/contrib/gcc-5.0/gcc/c-family/c-gimplify.c @@ -96,23 +96,23 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data) { hash_set *pset = (hash_set *) data; - /* Since walk_tree doesn't call the callback function on the decls - in BIND_EXPR_VARS, we have to walk them manually. */ if (TREE_CODE (*tp) == BIND_EXPR) { + /* Since walk_tree doesn't call the callback function on the decls + in BIND_EXPR_VARS, we have to walk them manually, so we can avoid + instrumenting DECL_INITIAL of TREE_STATIC vars. */ + *walk_subtrees = 0; for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl)) { if (TREE_STATIC (decl)) - { - *walk_subtrees = 0; - continue; - } + continue; walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset, pset); walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset); walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset, pset); } + walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset); } else if (TREE_CODE (*tp) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF) diff --git a/contrib/gcc-5.0/gcc/c-family/c-ppoutput.c b/contrib/gcc-5.0/gcc/c-family/c-ppoutput.c index 9b9cba06b3..f8a8da132b 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-ppoutput.c +++ b/contrib/gcc-5.0/gcc/c-family/c-ppoutput.c @@ -43,11 +43,11 @@ static struct const cpp_token *prev; /* Previous token. */ const cpp_token *source; /* Source token for spacing. */ int src_line; /* Line number currently being written. */ - unsigned char printed; /* Nonzero if something output at line. */ + bool printed; /* True if something output at line. */ bool first_time; /* pp_file_change hasn't been called yet. */ - const char *src_file; /* Current source file. */ bool prev_was_system_token; /* True if the previous token was a system token.*/ + const char *src_file; /* Current source file. */ } print; /* Defined and undefined macros being queued for output with -dU at @@ -165,7 +165,7 @@ init_pp_output (FILE *out_stream) /* Initialize the print structure. */ print.src_line = 1; - print.printed = 0; + print.printed = false; print.prev = 0; print.outf = out_stream; print.first_time = 1; @@ -218,12 +218,16 @@ scan_translation_unit (cpp_reader *pfile) { line_marker_emitted = do_line_change (pfile, token, loc, false); putc (' ', print.outf); + print.printed = true; } else if (print.source->flags & PREV_WHITE || (print.prev && cpp_avoid_paste (pfile, print.prev, token)) || (print.prev == NULL && token->type == CPP_HASH)) - putc (' ', print.outf); + { + putc (' ', print.outf); + print.printed = true; + } } else if (token->flags & PREV_WHITE) { @@ -234,6 +238,7 @@ scan_translation_unit (cpp_reader *pfile) && !in_pragma) line_marker_emitted = do_line_change (pfile, token, loc, false); putc (' ', print.outf); + print.printed = true; } avoid_paste = false; @@ -251,7 +256,7 @@ scan_translation_unit (cpp_reader *pfile) fprintf (print.outf, "%s %s", space, name); else fprintf (print.outf, "%s", name); - print.printed = 1; + print.printed = true; in_pragma = true; } else if (token->type == CPP_PRAGMA_EOL) @@ -262,23 +267,23 @@ scan_translation_unit (cpp_reader *pfile) else { if (cpp_get_options (parse_in)->debug) - linemap_dump_location (line_table, token->src_loc, - print.outf); + linemap_dump_location (line_table, token->src_loc, print.outf); if (do_line_adjustments && !in_pragma && !line_marker_emitted - && print.prev_was_system_token != !!in_system_header_at(loc) + && print.prev_was_system_token != !!in_system_header_at (loc) && !is_location_from_builtin_token (loc)) /* The system-ness of this token is different from the one of the previous token. Let's emit a line change to mark the new system-ness before we emit the token. */ { do_line_change (pfile, token, loc, false); - print.prev_was_system_token = !!in_system_header_at(loc); + print.prev_was_system_token = !!in_system_header_at (loc); } cpp_output_token (token, print.outf); line_marker_emitted = false; + print.printed = true; } /* CPP_COMMENT tokens and raw-string literal tokens can @@ -328,7 +333,7 @@ scan_translation_unit_trad (cpp_reader *pfile) size_t len = pfile->out.cur - pfile->out.base; maybe_print_line (pfile->out.first_line); fwrite (pfile->out.base, 1, len, print.outf); - print.printed = 1; + print.printed = true; if (!CPP_OPTION (pfile, discard_comments)) account_for_newlines (pfile->out.base, len); } @@ -351,7 +356,7 @@ maybe_print_line_1 (source_location src_loc, FILE *stream) { putc ('\n', stream); print.src_line++; - print.printed = 0; + print.printed = false; } if (!flag_no_line_commands @@ -397,7 +402,7 @@ print_line_1 (source_location src_loc, const char *special_flags, FILE *stream) /* End any previous line of text. */ if (print.printed) putc ('\n', stream); - print.printed = 0; + print.printed = false; if (!flag_no_line_commands) { @@ -472,7 +477,7 @@ do_line_change (cpp_reader *pfile, const cpp_token *token, if (!CPP_OPTION (pfile, traditional)) { int spaces = LOCATION_COLUMN (src_loc) - 2; - print.printed = 1; + print.printed = true; while (-- spaces >= 0) putc (' ', print.outf); @@ -515,6 +520,7 @@ cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node) fputs ((const char *) NODE_NAME (node), print.outf); putc ('\n', print.outf); + print.printed = false; linemap_resolve_location (line_table, line, LRK_MACRO_DEFINITION_LOCATION, &map); @@ -566,7 +572,7 @@ dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED) { putc ('\n', print.outf); print.src_line++; - print.printed = 0; + print.printed = false; } for (q = define_queue; q;) @@ -575,6 +581,7 @@ dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED) fputs ("#define ", print.outf); fputs (q->macro, print.outf); putc ('\n', print.outf); + print.printed = false; print.src_line++; oq = q; q = q->next; @@ -618,6 +625,7 @@ cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, } putc ('\n', print.outf); + print.printed = false; print.src_line++; } @@ -683,6 +691,7 @@ cb_def_pragma (cpp_reader *pfile, source_location line) maybe_print_line (line); fputs ("#pragma ", print.outf); cpp_output_line (pfile, print.outf); + print.printed = false; print.src_line++; } @@ -696,6 +705,7 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) fputs ((const char *) cpp_macro_definition (pfile, node), print.outf); putc ('\n', print.outf); + print.printed = false; print.src_line++; } diff --git a/contrib/gcc-5.0/gcc/c-family/c-pragma.c b/contrib/gcc-5.0/gcc/c-family/c-pragma.c index 6894f0e7c3..03c10397c8 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-pragma.c +++ b/contrib/gcc-5.0/gcc/c-family/c-pragma.c @@ -1273,6 +1273,13 @@ c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) return; } + if (id == PRAGMA_CILK_GRAINSIZE) + { + *space = "cilk"; + *name = "grainsize"; + return; + } + if (id >= PRAGMA_FIRST_EXTERNAL && (id < PRAGMA_FIRST_EXTERNAL + registered_pp_pragmas.length ())) { @@ -1459,7 +1466,7 @@ init_pragma (void) cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false, false); - if (flag_cilkplus && !flag_preprocess_only) + if (flag_cilkplus) cpp_register_deferred_pragma (parse_in, "cilk", "grainsize", PRAGMA_CILK_GRAINSIZE, true, false); diff --git a/contrib/gcc-5.0/gcc/c/c-decl.c b/contrib/gcc-5.0/gcc/c/c-decl.c index ad704bfbef..d1e74443f0 100644 --- a/contrib/gcc-5.0/gcc/c/c-decl.c +++ b/contrib/gcc-5.0/gcc/c/c-decl.c @@ -2376,6 +2376,35 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) DECL_ATTRIBUTES (newdecl) = targetm.merge_decl_attributes (olddecl, newdecl); + /* For typedefs use the old type, as the new type's DECL_NAME points + at newdecl, which will be ggc_freed. */ + if (TREE_CODE (newdecl) == TYPE_DECL) + { + /* But NEWTYPE might have an attribute, honor that. */ + tree tem = newtype; + newtype = oldtype; + + if (TYPE_USER_ALIGN (tem)) + { + if (TYPE_ALIGN (tem) > TYPE_ALIGN (newtype)) + TYPE_ALIGN (newtype) = TYPE_ALIGN (tem); + TYPE_USER_ALIGN (newtype) = true; + } + + /* And remove the new type from the variants list. */ + if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl) + { + tree remove = TREE_TYPE (newdecl); + for (tree t = TYPE_MAIN_VARIANT (remove); ; + t = TYPE_NEXT_VARIANT (t)) + if (TYPE_NEXT_VARIANT (t) == remove) + { + TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove); + break; + } + } + } + /* Merge the data types specified in the two decls. */ TREE_TYPE (newdecl) = TREE_TYPE (olddecl) @@ -5366,6 +5395,8 @@ grokdeclarator (const struct c_declarator *declarator, tree returned_attrs = NULL_TREE; bool bitfield = width != NULL; tree element_type; + tree orig_qual_type = NULL; + size_t orig_qual_indirect = 0; struct c_arg_info *arg_info = 0; addr_space_t as1, as2, address_space; location_t loc = UNKNOWN_LOCATION; @@ -5404,9 +5435,9 @@ grokdeclarator (const struct c_declarator *declarator, case cdk_function: case cdk_pointer: funcdef_syntax = (decl->kind == cdk_function); - decl = decl->declarator; if (first_non_attr_kind == cdk_attrs) first_non_attr_kind = decl->kind; + decl = decl->declarator; break; case cdk_attrs: @@ -5528,12 +5559,17 @@ grokdeclarator (const struct c_declarator *declarator, if ((TREE_CODE (type) == ARRAY_TYPE || first_non_attr_kind == cdk_array) && TYPE_QUALS (element_type)) - type = TYPE_MAIN_VARIANT (type); + { + orig_qual_type = type; + type = TYPE_MAIN_VARIANT (type); + } type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) | (volatilep ? TYPE_QUAL_VOLATILE : 0) | (atomicp ? TYPE_QUAL_ATOMIC : 0) | ENCODE_QUAL_ADDR_SPACE (address_space)); + if (type_quals != TYPE_QUALS (element_type)) + orig_qual_type = NULL_TREE; /* Applying the _Atomic qualifier to an array type (through the use of typedefs or typeof) must be detected here. If the qualifier @@ -6024,6 +6060,7 @@ grokdeclarator (const struct c_declarator *declarator, array_ptr_attrs = NULL_TREE; array_parm_static = 0; } + orig_qual_indirect++; break; } case cdk_function: @@ -6033,6 +6070,7 @@ grokdeclarator (const struct c_declarator *declarator, attributes. */ bool really_funcdef = false; tree arg_types; + orig_qual_type = NULL_TREE; if (funcdef_flag) { const struct c_declarator *t = declarator->declarator; @@ -6133,7 +6171,9 @@ grokdeclarator (const struct c_declarator *declarator, pedwarn (loc, OPT_Wpedantic, "ISO C forbids qualified function types"); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals, orig_qual_type, + orig_qual_indirect); + orig_qual_type = NULL_TREE; size_varies = false; /* When the pointed-to type involves components of variable size, @@ -6331,7 +6371,8 @@ grokdeclarator (const struct c_declarator *declarator, pedwarn (loc, OPT_Wpedantic, "ISO C forbids qualified function types"); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals, orig_qual_type, + orig_qual_indirect); decl = build_decl (declarator->id_loc, TYPE_DECL, declarator->u.id, type); if (declspecs->explicit_signed_p) @@ -6384,7 +6425,8 @@ grokdeclarator (const struct c_declarator *declarator, pedwarn (loc, OPT_Wpedantic, "ISO C forbids const or volatile function types"); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals, orig_qual_type, + orig_qual_indirect); return type; } @@ -6431,8 +6473,16 @@ grokdeclarator (const struct c_declarator *declarator, { /* Transfer const-ness of array into that of type pointed to. */ type = TREE_TYPE (type); + if (orig_qual_type != NULL_TREE) + { + if (orig_qual_indirect == 0) + orig_qual_type = TREE_TYPE (orig_qual_type); + else + orig_qual_indirect--; + } if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals, orig_qual_type, + orig_qual_indirect); type = c_build_pointer_type (type); type_quals = array_ptr_quals; if (type_quals) @@ -6523,7 +6573,8 @@ grokdeclarator (const struct c_declarator *declarator, TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node, NULL_TREE); } - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals, orig_qual_type, + orig_qual_indirect); decl = build_decl (declarator->id_loc, FIELD_DECL, declarator->u.id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; @@ -6635,7 +6686,8 @@ grokdeclarator (const struct c_declarator *declarator, /* An uninitialized decl with `extern' is a reference. */ int extern_ref = !initialized && storage_class == csc_extern; - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals, orig_qual_type, + orig_qual_indirect); /* C99 6.2.2p7: It is invalid (compile-time undefined behavior) to create an 'extern' declaration for a @@ -7996,7 +8048,22 @@ finish_enum (tree enumtype, tree values, tree attributes) precision = MAX (tree_int_cst_min_precision (minnode, sign), tree_int_cst_min_precision (maxnode, sign)); - if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node)) + /* If the precision of the type was specified with an attribute and it + was too small, give an error. Otherwise, use it. */ + if (TYPE_PRECISION (enumtype)) + { + if (precision > TYPE_PRECISION (enumtype)) + { + TYPE_PRECISION (enumtype) = 0; + error ("specified mode too small for enumeral values"); + } + else + precision = TYPE_PRECISION (enumtype); + } + + if (TYPE_PACKED (enumtype) + || precision > TYPE_PRECISION (integer_type_node) + || TYPE_PRECISION (enumtype)) { tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0); if (tem == NULL) @@ -8012,16 +8079,7 @@ finish_enum (tree enumtype, tree values, tree attributes) TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem); TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem); TYPE_SIZE (enumtype) = 0; - - /* If the precision of the type was specific with an attribute and it - was too small, give an error. Otherwise, use it. */ - if (TYPE_PRECISION (enumtype)) - { - if (precision > TYPE_PRECISION (enumtype)) - error ("specified mode too small for enumeral values"); - } - else - TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem); + TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem); layout_type (enumtype); diff --git a/contrib/gcc-5.0/gcc/c/c-parser.c b/contrib/gcc-5.0/gcc/c/c-parser.c index 86cbc404a4..c5378fec81 100644 --- a/contrib/gcc-5.0/gcc/c/c-parser.c +++ b/contrib/gcc-5.0/gcc/c/c-parser.c @@ -1206,7 +1206,8 @@ static tree c_parser_simple_asm_expr (c_parser *); static tree c_parser_attributes (c_parser *); static struct c_type_name *c_parser_type_name (c_parser *); static struct c_expr c_parser_initializer (c_parser *); -static struct c_expr c_parser_braced_init (c_parser *, tree, bool); +static struct c_expr c_parser_braced_init (c_parser *, tree, bool, + struct obstack *); static void c_parser_initelt (c_parser *, struct obstack *); static void c_parser_initval (c_parser *, struct c_expr *, struct obstack *); @@ -4159,7 +4160,7 @@ static struct c_expr c_parser_initializer (c_parser *parser) { if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) - return c_parser_braced_init (parser, NULL_TREE, false); + return c_parser_braced_init (parser, NULL_TREE, false, NULL); else { struct c_expr ret; @@ -4179,7 +4180,8 @@ c_parser_initializer (c_parser *parser) top-level initializer in a declaration. */ static struct c_expr -c_parser_braced_init (c_parser *parser, tree type, bool nested_p) +c_parser_braced_init (c_parser *parser, tree type, bool nested_p, + struct obstack *outer_obstack) { struct c_expr ret; struct obstack braced_init_obstack; @@ -4188,7 +4190,10 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); c_parser_consume_token (parser); if (nested_p) - push_init_level (brace_loc, 0, &braced_init_obstack); + { + finish_implicit_inits (brace_loc, outer_obstack); + push_init_level (brace_loc, 0, &braced_init_obstack); + } else really_start_incremental_init (type); if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) @@ -4443,7 +4448,8 @@ c_parser_initval (c_parser *parser, struct c_expr *after, location_t loc = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after) - init = c_parser_braced_init (parser, NULL_TREE, true); + init = c_parser_braced_init (parser, NULL_TREE, true, + braced_init_obstack); else { init = c_parser_expr_no_commas (parser, after); @@ -7746,7 +7752,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, error_at (type_loc, "compound literal has variable size"); type = error_mark_node; } - init = c_parser_braced_init (parser, type, false); + init = c_parser_braced_init (parser, type, false, NULL); finish_init (); maybe_warn_string_init (type_loc, type, init); diff --git a/contrib/gcc-5.0/gcc/c/c-tree.h b/contrib/gcc-5.0/gcc/c/c-tree.h index 7a7266500b..885bfd600f 100644 --- a/contrib/gcc-5.0/gcc/c/c-tree.h +++ b/contrib/gcc-5.0/gcc/c/c-tree.h @@ -614,6 +614,7 @@ extern void maybe_warn_string_init (location_t, tree, struct c_expr); extern void start_init (tree, tree, int); extern void finish_init (void); extern void really_start_incremental_init (tree); +extern void finish_implicit_inits (location_t, struct obstack *); extern void push_init_level (location_t, int, struct obstack *); extern struct c_expr pop_init_level (location_t, int, struct obstack *); extern void set_init_index (location_t, tree, tree, struct obstack *); diff --git a/contrib/gcc-5.0/gcc/c/c-typeck.c b/contrib/gcc-5.0/gcc/c/c-typeck.c index ffba66bb6c..be4967f7ee 100644 --- a/contrib/gcc-5.0/gcc/c/c-typeck.c +++ b/contrib/gcc-5.0/gcc/c/c-typeck.c @@ -7312,6 +7312,31 @@ really_start_incremental_init (tree type) } } +/* Called when we see an open brace for a nested initializer. Finish + off any pending levels with implicit braces. */ +void +finish_implicit_inits (location_t loc, struct obstack *braced_init_obstack) +{ + while (constructor_stack->implicit) + { + if ((TREE_CODE (constructor_type) == RECORD_TYPE + || TREE_CODE (constructor_type) == UNION_TYPE) + && constructor_fields == 0) + process_init_element (input_location, + pop_init_level (loc, 1, braced_init_obstack), + true, braced_init_obstack); + else if (TREE_CODE (constructor_type) == ARRAY_TYPE + && constructor_max_index + && tree_int_cst_lt (constructor_max_index, + constructor_index)) + process_init_element (input_location, + pop_init_level (loc, 1, braced_init_obstack), + true, braced_init_obstack); + else + break; + } +} + /* Push down into a subobject, for initialization. If this is for an explicit set of braces, IMPLICIT is 0. If it is because the next element belongs at a lower level, @@ -7324,34 +7349,6 @@ push_init_level (location_t loc, int implicit, struct constructor_stack *p; tree value = NULL_TREE; - /* If we've exhausted any levels that didn't have braces, - pop them now. If implicit == 1, this will have been done in - process_init_element; do not repeat it here because in the case - of excess initializers for an empty aggregate this leads to an - infinite cycle of popping a level and immediately recreating - it. */ - if (implicit != 1) - { - while (constructor_stack->implicit) - { - if ((TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - && constructor_fields == 0) - process_init_element (input_location, - pop_init_level (loc, 1, braced_init_obstack), - true, braced_init_obstack); - else if (TREE_CODE (constructor_type) == ARRAY_TYPE - && constructor_max_index - && tree_int_cst_lt (constructor_max_index, - constructor_index)) - process_init_element (input_location, - pop_init_level (loc, 1, braced_init_obstack), - true, braced_init_obstack); - else - break; - } - } - /* Unless this is an explicit brace, we need to preserve previous content if any. */ if (implicit) @@ -7783,6 +7780,7 @@ set_designator (location_t loc, int array, } constructor_designated = 1; + finish_implicit_inits (loc, braced_init_obstack); push_init_level (loc, 2, braced_init_obstack); return 0; } @@ -9168,6 +9166,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, p = p->next; if (!p) break; + finish_implicit_inits (loc, braced_init_obstack); push_init_level (loc, 2, braced_init_obstack); p->stack = constructor_stack; if (p->range_end && tree_int_cst_equal (p->index, p->range_end)) @@ -10754,6 +10753,20 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + warning_at (location, OPT_Wsign_compare, "comparison between " + "types %qT and %qT", type0, type1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); @@ -10896,6 +10909,20 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + warning_at (location, OPT_Wsign_compare, "comparison between " + "types %qT and %qT", type0, type1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); @@ -12578,10 +12605,15 @@ c_finish_transaction (location_t loc, tree block, int flags) } /* Make a variant type in the proper way for C/C++, propagating qualifiers - down to the element type of an array. */ + down to the element type of an array. If ORIG_QUAL_TYPE is not + NULL, then it should be used as the qualified type + ORIG_QUAL_INDIRECT levels down in array type derivation (to + preserve information about the typedef name from which an array + type was derived). */ tree -c_build_qualified_type (tree type, int type_quals) +c_build_qualified_type (tree type, int type_quals, tree orig_qual_type, + size_t orig_qual_indirect) { if (type == error_mark_node) return type; @@ -12590,18 +12622,22 @@ c_build_qualified_type (tree type, int type_quals) { tree t; tree element_type = c_build_qualified_type (TREE_TYPE (type), - type_quals); + type_quals, orig_qual_type, + orig_qual_indirect - 1); /* See if we already have an identically qualified type. */ - for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - { - if (TYPE_QUALS (strip_array_types (t)) == type_quals - && TYPE_NAME (t) == TYPE_NAME (type) - && TYPE_CONTEXT (t) == TYPE_CONTEXT (type) - && attribute_list_equal (TYPE_ATTRIBUTES (t), - TYPE_ATTRIBUTES (type))) - break; - } + if (orig_qual_type && orig_qual_indirect == 0) + t = orig_qual_type; + else + for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) + { + if (TYPE_QUALS (strip_array_types (t)) == type_quals + && TYPE_NAME (t) == TYPE_NAME (type) + && TYPE_CONTEXT (t) == TYPE_CONTEXT (type) + && attribute_list_equal (TYPE_ATTRIBUTES (t), + TYPE_ATTRIBUTES (type))) + break; + } if (!t) { tree domain = TYPE_DOMAIN (type); @@ -12639,7 +12675,10 @@ c_build_qualified_type (tree type, int type_quals) type_quals &= ~TYPE_QUAL_RESTRICT; } - return build_qualified_type (type, type_quals); + tree var_type = (orig_qual_type && orig_qual_indirect == 0 + ? orig_qual_type + : build_qualified_type (type, type_quals)); + return var_type; } /* Build a VA_ARG_EXPR for the C parser. */ diff --git a/contrib/gcc-5.0/gcc/calls.c b/contrib/gcc-5.0/gcc/calls.c index ee8ea5f768..29b4ed18ce 100644 --- a/contrib/gcc-5.0/gcc/calls.c +++ b/contrib/gcc-5.0/gcc/calls.c @@ -576,12 +576,9 @@ special_function_p (const_tree fndecl, int flags) /* We assume that alloca will always be called by name. It makes no sense to pass it as a pointer-to-function to anything that does not understand its behavior. */ - if (((IDENTIFIER_LENGTH (name_decl) == 6 - && name[0] == 'a' - && ! strcmp (name, "alloca")) - || (IDENTIFIER_LENGTH (name_decl) == 16 - && name[0] == '_' - && ! strcmp (name, "__builtin_alloca")))) + if (IDENTIFIER_LENGTH (name_decl) == 6 + && name[0] == 'a' + && ! strcmp (name, "alloca")) flags |= ECF_MAY_BE_ALLOCA; /* Disregard prefix _, __, __x or __builtin_. */ @@ -627,6 +624,17 @@ special_function_p (const_tree fndecl, int flags) flags |= ECF_NORETURN; } + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + switch (DECL_FUNCTION_CODE (fndecl)) + { + case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: + flags |= ECF_MAY_BE_ALLOCA; + break; + default: + break; + } + return flags; } diff --git a/contrib/gcc-5.0/gcc/cfgexpand.c b/contrib/gcc-5.0/gcc/cfgexpand.c index 3293ea60cd..ffa120a271 100644 --- a/contrib/gcc-5.0/gcc/cfgexpand.c +++ b/contrib/gcc-5.0/gcc/cfgexpand.c @@ -3367,6 +3367,12 @@ expand_gimple_stmt_1 (gimple stmt) { tree result = DECL_RESULT (current_function_decl); + /* Mark we have return statement with missing bounds. */ + if (!bnd + && chkp_function_instrumented_p (cfun->decl) + && !DECL_P (op0)) + bnd = error_mark_node; + /* If we are not returning the current function's RESULT_DECL, build an assignment to it. */ if (op0 != result) @@ -3383,9 +3389,6 @@ expand_gimple_stmt_1 (gimple stmt) op0 = build2 (MODIFY_EXPR, TREE_TYPE (result), result, op0); } - /* Mark we have return statement with missing bounds. */ - if (!bnd && chkp_function_instrumented_p (cfun->decl)) - bnd = error_mark_node; } if (!op0) diff --git a/contrib/gcc-5.0/gcc/cgraph.c b/contrib/gcc-5.0/gcc/cgraph.c index 852960a817..e25ecb3fb9 100644 --- a/contrib/gcc-5.0/gcc/cgraph.c +++ b/contrib/gcc-5.0/gcc/cgraph.c @@ -2609,7 +2609,8 @@ collect_callers_of_node_1 (cgraph_node *node, void *data) if (avail > AVAIL_INTERPOSABLE) for (cs = node->callers; cs != NULL; cs = cs->next_caller) - if (!cs->indirect_inlining_edge) + if (!cs->indirect_inlining_edge + && !cs->caller->thunk.thunk_p) redirect_callers->safe_push (cs); return false; } @@ -3312,7 +3313,10 @@ cgraph_node::get_body (void) { opt_pass *saved_current_pass = current_pass; FILE *saved_dump_file = dump_file; + const char *saved_dump_file_name = dump_file_name; int saved_dump_flags = dump_flags; + dump_file_name = NULL; + dump_file = NULL; push_cfun (DECL_STRUCT_FUNCTION (decl)); execute_all_ipa_transforms (); @@ -3324,6 +3328,7 @@ cgraph_node::get_body (void) current_pass = saved_current_pass; dump_file = saved_dump_file; + dump_file_name = saved_dump_file_name; dump_flags = saved_dump_flags; } return updated; diff --git a/contrib/gcc-5.0/gcc/cgraph.h b/contrib/gcc-5.0/gcc/cgraph.h index cf8c7b64b9..e3689968e9 100644 --- a/contrib/gcc-5.0/gcc/cgraph.h +++ b/contrib/gcc-5.0/gcc/cgraph.h @@ -1028,7 +1028,7 @@ public: cgraph_edge *get_edge (gimple call_stmt); /* Collect all callers of cgraph_node and its aliases that are known to lead - to NODE (i.e. are not overwritable). */ + to NODE (i.e. are not overwritable) and that are not thunks. */ vec collect_callers (void); /* Remove all callers from the node. */ diff --git a/contrib/gcc-5.0/gcc/cgraphclones.c b/contrib/gcc-5.0/gcc/cgraphclones.c index b587ff2cb7..546cac8656 100644 --- a/contrib/gcc-5.0/gcc/cgraphclones.c +++ b/contrib/gcc-5.0/gcc/cgraphclones.c @@ -367,6 +367,7 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node) new_thunk = cgraph_node::create (new_decl); set_new_clone_decl_and_node_flags (new_thunk); new_thunk->definition = true; + new_thunk->local.can_change_signature = node->local.can_change_signature; new_thunk->thunk = thunk->thunk; new_thunk->unique_name = in_lto_p; new_thunk->former_clone_of = thunk->decl; diff --git a/contrib/gcc-5.0/gcc/cgraphunit.c b/contrib/gcc-5.0/gcc/cgraphunit.c index 78b2b59f4f..d4db126cbd 100644 --- a/contrib/gcc-5.0/gcc/cgraphunit.c +++ b/contrib/gcc-5.0/gcc/cgraphunit.c @@ -585,6 +585,7 @@ cgraph_node::analyze (void) cgraph_node *t = cgraph_node::get (thunk.alias); create_edge (t, NULL, 0, CGRAPH_FREQ_BASE); + callees->can_throw_external = !TREE_NOTHROW (t->decl); /* Target code in expand_thunk may need the thunk's target to be analyzed, so recurse here. */ if (!t->analyzed) diff --git a/contrib/gcc-5.0/gcc/combine.c b/contrib/gcc-5.0/gcc/combine.c index ea47b32def..fb3215370d 100644 --- a/contrib/gcc-5.0/gcc/combine.c +++ b/contrib/gcc-5.0/gcc/combine.c @@ -7227,6 +7227,10 @@ expand_field_assignment (const_rtx x) if (len >= HOST_BITS_PER_WIDE_INT) break; + /* Don't try to compute in too wide unsupported modes. */ + if (!targetm.scalar_mode_supported_p (compute_mode)) + break; + /* Now compute the equivalent expression. Make a copy of INNER for the SET_DEST in case it is a MEM into which we will substitute; we don't want shared RTL in that case. */ @@ -10472,9 +10476,24 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode, && CONST_INT_P (XEXP (varop, 0)) && !CONST_INT_P (XEXP (varop, 1))) { + /* For ((unsigned) (cstULL >> count)) >> cst2 we have to make + sure the result will be masked. See PR70222. */ + if (code == LSHIFTRT + && mode != result_mode + && !merge_outer_ops (&outer_op, &outer_const, AND, + GET_MODE_MASK (result_mode) + >> orig_count, result_mode, + &complement_p)) + break; + /* For ((int) (cstLL >> count)) >> cst2 just give up. Queuing + up outer sign extension (often left and right shift) is + hardly more efficient than the original. See PR70429. */ + if (code == ASHIFTRT && mode != result_mode) + break; + rtx new_rtx = simplify_const_binary_operation (code, mode, - XEXP (varop, 0), - GEN_INT (count)); + XEXP (varop, 0), + GEN_INT (count)); varop = gen_rtx_fmt_ee (code, mode, new_rtx, XEXP (varop, 1)); count = 0; continue; @@ -13022,6 +13041,12 @@ get_last_value (const_rtx x) && DF_INSN_LUID (rsp->last_set) >= subst_low_luid) return 0; + /* If fewer bits were set than what we are asked for now, we cannot use + the value. */ + if (GET_MODE_PRECISION (rsp->last_set_mode) + < GET_MODE_PRECISION (GET_MODE (x))) + return 0; + /* If the value has all its registers valid, return it. */ if (get_last_value_validate (&value, rsp->last_set, rsp->last_set_label, 0)) return value; @@ -13781,10 +13806,10 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2, break; tem_insn = i3; /* If the new I2 sets the same register that is marked dead - in the note, the note now should not be put on I2, as the - note refers to a previous incarnation of the reg. */ + in the note, we do not know where to put the note. + Give up. */ if (i2 != 0 && reg_set_p (XEXP (note, 0), PATTERN (i2))) - tem_insn = i2; + break; } if (place == 0) diff --git a/contrib/gcc-5.0/gcc/common.opt b/contrib/gcc-5.0/gcc/common.opt index 1218a71fe4..429811e585 100644 --- a/contrib/gcc-5.0/gcc/common.opt +++ b/contrib/gcc-5.0/gcc/common.opt @@ -1845,7 +1845,7 @@ Common Var(common_deferred_options) Defer frandom-seed= Common Joined RejectNegative Var(common_deferred_options) Defer --frandom-seed= Make compile reproducible using +-frandom-seed= Make compile reproducible using ; This switch causes the command line that was used to create an ; object file to be recorded into the object file. The exact format diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512bwintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512bwintrin.h index 3114849fdd..7a7ed68c99 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512bwintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512bwintrin.h @@ -270,9 +270,8 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_broadcastb_epi8 (__m128i __A) { return (__m512i) __builtin_ia32_pbroadcastb512_mask ((__v16qi) __A, - (__v64qi)_mm512_undefined_si512(), - (__mmask64) - - 1); + (__v64qi)_mm512_undefined_epi32(), + (__mmask64) -1); } extern __inline __m512i @@ -318,8 +317,8 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_broadcastw_epi16 (__m128i __A) { return (__m512i) __builtin_ia32_pbroadcastw512_mask ((__v8hi) __A, - (__v32hi)_mm512_undefined_si512(), - (__mmask32)-1); + (__v32hi)_mm512_undefined_epi32(), + (__mmask32) -1); } extern __inline __m512i @@ -588,8 +587,7 @@ _mm512_permutex2var_epi16 (__m512i __A, __m512i __I, __m512i __B) /* idx */ , (__v32hi) __A, (__v32hi) __B, - (__mmask32) - - 1); + (__mmask32) -1); } extern __inline __m512i @@ -2284,7 +2282,7 @@ _mm512_cmpneq_epu8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_ucmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 4, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask64 @@ -2293,7 +2291,7 @@ _mm512_cmplt_epu8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_ucmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 1, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask64 @@ -2302,7 +2300,7 @@ _mm512_cmpge_epu8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_ucmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 5, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask64 @@ -2311,7 +2309,7 @@ _mm512_cmple_epu8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_ucmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 2, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask32 @@ -2320,7 +2318,7 @@ _mm512_cmpneq_epu16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_ucmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 4, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2329,7 +2327,7 @@ _mm512_cmplt_epu16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_ucmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 1, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2338,7 +2336,7 @@ _mm512_cmpge_epu16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_ucmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 5, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2347,7 +2345,7 @@ _mm512_cmple_epu16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_ucmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 2, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask64 @@ -2356,7 +2354,7 @@ _mm512_cmpneq_epi8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_cmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 4, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask64 @@ -2365,7 +2363,7 @@ _mm512_cmplt_epi8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_cmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 1, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask64 @@ -2374,7 +2372,7 @@ _mm512_cmpge_epi8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_cmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 5, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask64 @@ -2383,7 +2381,7 @@ _mm512_cmple_epi8_mask (__m512i __X, __m512i __Y) { return (__mmask64) __builtin_ia32_cmpb512_mask ((__v64qi) __X, (__v64qi) __Y, 2, - (__mmask64) - 1); + (__mmask64) -1); } extern __inline __mmask32 @@ -2392,7 +2390,7 @@ _mm512_cmpneq_epi16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_cmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 4, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2401,7 +2399,7 @@ _mm512_cmplt_epi16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_cmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 1, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2410,7 +2408,7 @@ _mm512_cmpge_epi16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_cmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 5, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2419,7 +2417,7 @@ _mm512_cmple_epi16_mask (__m512i __X, __m512i __Y) { return (__mmask32) __builtin_ia32_cmpw512_mask ((__v32hi) __X, (__v32hi) __Y, 2, - (__mmask32) - 1); + (__mmask32) -1); } #ifdef __OPTIMIZE__ diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512dqintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512dqintrin.h index b36ef48f2a..dd46f72a8e 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512dqintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512dqintrin.h @@ -41,8 +41,7 @@ _mm512_broadcast_f64x2 (__m128d __A) return (__m512d) __builtin_ia32_broadcastf64x2_512_mask ((__v2df) __A, _mm512_undefined_pd(), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m512d @@ -72,9 +71,8 @@ _mm512_broadcast_i64x2 (__m128i __A) { return (__m512i) __builtin_ia32_broadcasti64x2_512_mask ((__v2di) __A, - _mm512_undefined_si512(), - (__mmask8) - - 1); + _mm512_undefined_epi32(), + (__mmask8) -1); } extern __inline __m512i @@ -104,8 +102,7 @@ _mm512_broadcast_f32x2 (__m128 __A) { return (__m512) __builtin_ia32_broadcastf32x2_512_mask ((__v4sf) __A, (__v16sf)_mm512_undefined_ps(), - (__mmask16) - - 1); + (__mmask16) -1); } extern __inline __m512 @@ -133,9 +130,8 @@ _mm512_broadcast_i32x2 (__m128i __A) { return (__m512i) __builtin_ia32_broadcasti32x2_512_mask ((__v4si) __A, - (__v16si)_mm512_undefined_si512(), - (__mmask16) - -1); + (__v16si)_mm512_undefined_epi32(), + (__mmask16) -1); } extern __inline __m512i @@ -165,8 +161,7 @@ _mm512_broadcast_f32x8 (__m256 __A) { return (__m512) __builtin_ia32_broadcastf32x8_512_mask ((__v8sf) __A, _mm512_undefined_ps(), - (__mmask16) - - 1); + (__mmask16) -1); } extern __inline __m512 @@ -194,9 +189,8 @@ _mm512_broadcast_i32x8 (__m256i __A) { return (__m512i) __builtin_ia32_broadcasti32x8_512_mask ((__v8si) __A, - (__v16si)_mm512_undefined_si512(), - (__mmask16) - -1); + (__v16si)_mm512_undefined_epi32(), + (__mmask16) -1); } extern __inline __m512i @@ -1569,8 +1563,7 @@ _mm512_extractf64x2_pd (__m512d __A, const int __imm) __imm, (__v2df) _mm_setzero_pd (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128d @@ -1640,8 +1633,7 @@ _mm512_extracti64x2_epi64 (__m512i __A, const int __imm) __imm, (__v2di) _mm_setzero_di (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128i @@ -1829,8 +1821,7 @@ _mm512_inserti64x2 (__m512i __A, __m128i __B, const int __imm) __imm, (__v8di) _mm512_setzero_si512 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m512i @@ -1869,8 +1860,7 @@ _mm512_insertf64x2 (__m512d __A, __m128d __B, const int __imm) __imm, (__v8df) _mm512_setzero_pd (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m512d @@ -1933,8 +1923,7 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm) { return (__mmask16) __builtin_ia32_fpclassps512_mask ((__v16sf) __A, __imm, - (__mmask16) - - 1); + (__mmask16) -1); } #else diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512fintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512fintrin.h index d7e7020577..184e9e88d6 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512fintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512fintrin.h @@ -130,12 +130,14 @@ _mm512_undefined_pd (void) extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_undefined_si512 (void) +_mm512_undefined_epi32 (void) { __m512i __Y = __Y; return __Y; } +#define _mm512_undefined_si512 _mm512_undefined_epi32 + extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_set1_epi8 (char __A) @@ -549,7 +551,7 @@ _mm512_sllv_epi32 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_psllv16si_mask ((__v16si) __X, (__v16si) __Y, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -581,7 +583,7 @@ _mm512_srav_epi32 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_psrav16si_mask ((__v16si) __X, (__v16si) __Y, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -613,7 +615,7 @@ _mm512_srlv_epi32 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_psrlv16si_mask ((__v16si) __X, (__v16si) __Y, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -733,7 +735,7 @@ _mm512_srav_epi64 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_psrav8di_mask ((__v8di) __X, (__v8di) __Y, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -765,7 +767,7 @@ _mm512_srlv_epi64 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_psrlv8di_mask ((__v8di) __X, (__v8di) __Y, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -825,7 +827,7 @@ _mm512_mul_epi32 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_pmuldq512_mask ((__v16si) __X, (__v16si) __Y, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -884,7 +886,7 @@ _mm512_mul_epu32 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_pmuludq512_mask ((__v16si) __X, (__v16si) __Y, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -915,7 +917,7 @@ _mm512_slli_epi64 (__m512i __A, unsigned int __B) { return (__m512i) __builtin_ia32_psllqi512_mask ((__v8di) __A, __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -941,7 +943,7 @@ _mm512_maskz_slli_epi64 (__mmask8 __U, __m512i __A, unsigned int __B) #else #define _mm512_slli_epi64(X, C) \ ((__m512i) __builtin_ia32_psllqi512_mask ((__v8di)(__m512i)(X), (int)(C),\ - (__v8di)(__m512i)_mm512_undefined_si512 (),\ + (__v8di)(__m512i)_mm512_undefined_epi32 (),\ (__mmask8)-1)) #define _mm512_mask_slli_epi64(W, U, X, C) \ @@ -962,7 +964,7 @@ _mm512_sll_epi64 (__m512i __A, __m128i __B) return (__m512i) __builtin_ia32_psllq512_mask ((__v8di) __A, (__v2di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -994,7 +996,7 @@ _mm512_srli_epi64 (__m512i __A, unsigned int __B) { return (__m512i) __builtin_ia32_psrlqi512_mask ((__v8di) __A, __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1020,7 +1022,7 @@ _mm512_maskz_srli_epi64 (__mmask8 __U, __m512i __A, unsigned int __B) #else #define _mm512_srli_epi64(X, C) \ ((__m512i) __builtin_ia32_psrlqi512_mask ((__v8di)(__m512i)(X), (int)(C),\ - (__v8di)(__m512i)_mm512_undefined_si512 (),\ + (__v8di)(__m512i)_mm512_undefined_epi32 (),\ (__mmask8)-1)) #define _mm512_mask_srli_epi64(W, U, X, C) \ @@ -1041,7 +1043,7 @@ _mm512_srl_epi64 (__m512i __A, __m128i __B) return (__m512i) __builtin_ia32_psrlq512_mask ((__v8di) __A, (__v2di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1073,7 +1075,7 @@ _mm512_srai_epi64 (__m512i __A, unsigned int __B) { return (__m512i) __builtin_ia32_psraqi512_mask ((__v8di) __A, __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1099,7 +1101,7 @@ _mm512_maskz_srai_epi64 (__mmask8 __U, __m512i __A, unsigned int __B) #else #define _mm512_srai_epi64(X, C) \ ((__m512i) __builtin_ia32_psraqi512_mask ((__v8di)(__m512i)(X), (int)(C),\ - (__v8di)(__m512i)_mm512_undefined_si512 (),\ + (__v8di)(__m512i)_mm512_undefined_epi32 (),\ (__mmask8)-1)) #define _mm512_mask_srai_epi64(W, U, X, C) \ @@ -1120,7 +1122,7 @@ _mm512_sra_epi64 (__m512i __A, __m128i __B) return (__m512i) __builtin_ia32_psraq512_mask ((__v8di) __A, (__v2di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1152,7 +1154,7 @@ _mm512_slli_epi32 (__m512i __A, unsigned int __B) { return (__m512i) __builtin_ia32_pslldi512_mask ((__v16si) __A, __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1178,7 +1180,7 @@ _mm512_maskz_slli_epi32 (__mmask16 __U, __m512i __A, unsigned int __B) #else #define _mm512_slli_epi32(X, C) \ ((__m512i) __builtin_ia32_pslldi512_mask ((__v16si)(__m512i)(X), (int)(C),\ - (__v16si)(__m512i)_mm512_undefined_si512 (),\ + (__v16si)(__m512i)_mm512_undefined_epi32 (),\ (__mmask16)-1)) #define _mm512_mask_slli_epi32(W, U, X, C) \ @@ -1199,7 +1201,7 @@ _mm512_sll_epi32 (__m512i __A, __m128i __B) return (__m512i) __builtin_ia32_pslld512_mask ((__v16si) __A, (__v4si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1231,7 +1233,7 @@ _mm512_srli_epi32 (__m512i __A, unsigned int __B) { return (__m512i) __builtin_ia32_psrldi512_mask ((__v16si) __A, __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1257,7 +1259,7 @@ _mm512_maskz_srli_epi32 (__mmask16 __U, __m512i __A, unsigned int __B) #else #define _mm512_srli_epi32(X, C) \ ((__m512i) __builtin_ia32_psrldi512_mask ((__v16si)(__m512i)(X), (int)(C),\ - (__v16si)(__m512i)_mm512_undefined_si512 (),\ + (__v16si)(__m512i)_mm512_undefined_epi32 (),\ (__mmask16)-1)) #define _mm512_mask_srli_epi32(W, U, X, C) \ @@ -1278,7 +1280,7 @@ _mm512_srl_epi32 (__m512i __A, __m128i __B) return (__m512i) __builtin_ia32_psrld512_mask ((__v16si) __A, (__v4si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1310,7 +1312,7 @@ _mm512_srai_epi32 (__m512i __A, unsigned int __B) { return (__m512i) __builtin_ia32_psradi512_mask ((__v16si) __A, __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1336,7 +1338,7 @@ _mm512_maskz_srai_epi32 (__mmask16 __U, __m512i __A, unsigned int __B) #else #define _mm512_srai_epi32(X, C) \ ((__m512i) __builtin_ia32_psradi512_mask ((__v16si)(__m512i)(X), (int)(C),\ - (__v16si)(__m512i)_mm512_undefined_si512 (),\ + (__v16si)(__m512i)_mm512_undefined_epi32 (),\ (__mmask16)-1)) #define _mm512_mask_srai_epi32(W, U, X, C) \ @@ -1357,7 +1359,7 @@ _mm512_sra_epi32 (__m512i __A, __m128i __B) return (__m512i) __builtin_ia32_psrad512_mask ((__v16si) __A, (__v4si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1778,7 +1780,7 @@ _mm512_cvtepi8_epi32 (__m128i __A) { return (__m512i) __builtin_ia32_pmovsxbd512_mask ((__v16qi) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1807,7 +1809,7 @@ _mm512_cvtepi8_epi64 (__m128i __A) { return (__m512i) __builtin_ia32_pmovsxbq512_mask ((__v16qi) __A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1836,7 +1838,7 @@ _mm512_cvtepi16_epi32 (__m256i __A) { return (__m512i) __builtin_ia32_pmovsxwd512_mask ((__v16hi) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1865,7 +1867,7 @@ _mm512_cvtepi16_epi64 (__m128i __A) { return (__m512i) __builtin_ia32_pmovsxwq512_mask ((__v8hi) __A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1894,7 +1896,7 @@ _mm512_cvtepi32_epi64 (__m256i __X) { return (__m512i) __builtin_ia32_pmovsxdq512_mask ((__v8si) __X, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1923,7 +1925,7 @@ _mm512_cvtepu8_epi32 (__m128i __A) { return (__m512i) __builtin_ia32_pmovzxbd512_mask ((__v16qi) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -1952,7 +1954,7 @@ _mm512_cvtepu8_epi64 (__m128i __A) { return (__m512i) __builtin_ia32_pmovzxbq512_mask ((__v16qi) __A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -1981,7 +1983,7 @@ _mm512_cvtepu16_epi32 (__m256i __A) { return (__m512i) __builtin_ia32_pmovzxwd512_mask ((__v16hi) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -2010,7 +2012,7 @@ _mm512_cvtepu16_epi64 (__m128i __A) { return (__m512i) __builtin_ia32_pmovzxwq512_mask ((__v8hi) __A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -2039,7 +2041,7 @@ _mm512_cvtepu32_epi64 (__m256i __X) { return (__m512i) __builtin_ia32_pmovzxdq512_mask ((__v8si) __X, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -3407,7 +3409,7 @@ _mm512_abs_epi64 (__m512i __A) { return (__m512i) __builtin_ia32_pabsq512_mask ((__v8di) __A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -3436,7 +3438,7 @@ _mm512_abs_epi32 (__m512i __A) { return (__m512i) __builtin_ia32_pabsd512_mask ((__v16si) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -3521,7 +3523,7 @@ _mm512_broadcastd_epi32 (__m128i __A) { return (__m512i) __builtin_ia32_pbroadcastd512 ((__v4si) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -3549,7 +3551,7 @@ _mm512_set1_epi32 (int __A) { return (__m512i) __builtin_ia32_pbroadcastd512_gpr_mask (__A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16)(-1)); } @@ -3577,7 +3579,7 @@ _mm512_broadcastq_epi64 (__m128i __A) { return (__m512i) __builtin_ia32_pbroadcastq512 ((__v2di) __A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -3605,7 +3607,7 @@ _mm512_set1_epi64 (long long __A) { return (__m512i) __builtin_ia32_pbroadcastq512_gpr_mask (__A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8)(-1)); } @@ -3662,7 +3664,7 @@ _mm512_broadcast_i32x4 (__m128i __A) { return (__m512i) __builtin_ia32_broadcasti32x4_512 ((__v4si) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -3720,7 +3722,7 @@ _mm512_broadcast_i64x4 (__m256i __A) { return (__m512i) __builtin_ia32_broadcasti64x4_512 ((__v4di) __A, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -3841,7 +3843,7 @@ _mm512_shuffle_epi32 (__m512i __A, _MM_PERM_ENUM __mask) return (__m512i) __builtin_ia32_pshufd512_mask ((__v16si) __A, __mask, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -3874,7 +3876,7 @@ _mm512_shuffle_i64x2 (__m512i __A, __m512i __B, const int __imm) return (__m512i) __builtin_ia32_shuf_i64x2_mask ((__v8di) __A, (__v8di) __B, __imm, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -3909,7 +3911,7 @@ _mm512_shuffle_i32x4 (__m512i __A, __m512i __B, const int __imm) (__v16si) __B, __imm, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -4009,7 +4011,7 @@ _mm512_maskz_shuffle_f32x4 (__mmask16 __U, __m512 __A, __m512 __B, #else #define _mm512_shuffle_epi32(X, C) \ ((__m512i) __builtin_ia32_pshufd512_mask ((__v16si)(__m512i)(X), (int)(C),\ - (__v16si)(__m512i)_mm512_undefined_si512 (),\ + (__v16si)(__m512i)_mm512_undefined_epi32 (),\ (__mmask16)-1)) #define _mm512_mask_shuffle_epi32(W, U, X, C) \ @@ -4025,7 +4027,7 @@ _mm512_maskz_shuffle_f32x4 (__mmask16 __U, __m512 __A, __m512 __B, #define _mm512_shuffle_i64x2(X, Y, C) \ ((__m512i) __builtin_ia32_shuf_i64x2_mask ((__v8di)(__m512i)(X), \ (__v8di)(__m512i)(Y), (int)(C),\ - (__v8di)(__m512i)_mm512_undefined_si512 (),\ + (__v8di)(__m512i)_mm512_undefined_epi32 (),\ (__mmask8)-1)) #define _mm512_mask_shuffle_i64x2(W, U, X, Y, C) \ @@ -4043,7 +4045,7 @@ _mm512_maskz_shuffle_f32x4 (__mmask16 __U, __m512 __A, __m512 __B, #define _mm512_shuffle_i32x4(X, Y, C) \ ((__m512i) __builtin_ia32_shuf_i32x4_mask ((__v16si)(__m512i)(X), \ (__v16si)(__m512i)(Y), (int)(C),\ - (__v16si)(__m512i)_mm512_undefined_si512 (),\ + (__v16si)(__m512i)_mm512_undefined_epi32 (),\ (__mmask16)-1)) #define _mm512_mask_shuffle_i32x4(W, U, X, Y, C) \ @@ -4102,7 +4104,7 @@ _mm512_rolv_epi32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_prolvd512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -4134,7 +4136,7 @@ _mm512_rorv_epi32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_prorvd512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -4166,7 +4168,7 @@ _mm512_rolv_epi64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_prolvq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -4198,7 +4200,7 @@ _mm512_rorv_epi64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_prorvq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -4390,7 +4392,7 @@ _mm512_cvtt_roundps_epi32 (__m512 __A, const int __R) { return (__m512i) __builtin_ia32_cvttps2dq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, __R); } @@ -4420,7 +4422,7 @@ _mm512_cvtt_roundps_epu32 (__m512 __A, const int __R) { return (__m512i) __builtin_ia32_cvttps2udq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, __R); } @@ -4445,7 +4447,7 @@ _mm512_maskz_cvtt_roundps_epu32 (__mmask16 __U, __m512 __A, const int __R) } #else #define _mm512_cvtt_roundps_epi32(A, B) \ - ((__m512i)__builtin_ia32_cvttps2dq512_mask(A, (__v16si)_mm512_undefined_si512 (), -1, B)) + ((__m512i)__builtin_ia32_cvttps2dq512_mask(A, (__v16si)_mm512_undefined_epi32 (), -1, B)) #define _mm512_mask_cvtt_roundps_epi32(W, U, A, B) \ ((__m512i)__builtin_ia32_cvttps2dq512_mask(A, (__v16si)(W), U, B)) @@ -4454,7 +4456,7 @@ _mm512_maskz_cvtt_roundps_epu32 (__mmask16 __U, __m512 __A, const int __R) ((__m512i)__builtin_ia32_cvttps2dq512_mask(A, (__v16si)_mm512_setzero_si512 (), U, B)) #define _mm512_cvtt_roundps_epu32(A, B) \ - ((__m512i)__builtin_ia32_cvttps2udq512_mask(A, (__v16si)_mm512_undefined_si512 (), -1, B)) + ((__m512i)__builtin_ia32_cvttps2udq512_mask(A, (__v16si)_mm512_undefined_epi32 (), -1, B)) #define _mm512_mask_cvtt_roundps_epu32(W, U, A, B) \ ((__m512i)__builtin_ia32_cvttps2udq512_mask(A, (__v16si)(W), U, B)) @@ -4470,7 +4472,7 @@ _mm512_cvt_roundps_epi32 (__m512 __A, const int __R) { return (__m512i) __builtin_ia32_cvtps2dq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, __R); } @@ -4500,7 +4502,7 @@ _mm512_cvt_roundps_epu32 (__m512 __A, const int __R) { return (__m512i) __builtin_ia32_cvtps2udq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, __R); } @@ -4525,7 +4527,7 @@ _mm512_maskz_cvt_roundps_epu32 (__mmask16 __U, __m512 __A, const int __R) } #else #define _mm512_cvt_roundps_epi32(A, B) \ - ((__m512i)__builtin_ia32_cvtps2dq512_mask(A, (__v16si)_mm512_undefined_si512 (), -1, B)) + ((__m512i)__builtin_ia32_cvtps2dq512_mask(A, (__v16si)_mm512_undefined_epi32 (), -1, B)) #define _mm512_mask_cvt_roundps_epi32(W, U, A, B) \ ((__m512i)__builtin_ia32_cvtps2dq512_mask(A, (__v16si)(W), U, B)) @@ -4534,7 +4536,7 @@ _mm512_maskz_cvt_roundps_epu32 (__mmask16 __U, __m512 __A, const int __R) ((__m512i)__builtin_ia32_cvtps2dq512_mask(A, (__v16si)_mm512_setzero_si512 (), U, B)) #define _mm512_cvt_roundps_epu32(A, B) \ - ((__m512i)__builtin_ia32_cvtps2udq512_mask(A, (__v16si)_mm512_undefined_si512 (), -1, B)) + ((__m512i)__builtin_ia32_cvtps2udq512_mask(A, (__v16si)_mm512_undefined_epi32 (), -1, B)) #define _mm512_mask_cvt_roundps_epu32(W, U, A, B) \ ((__m512i)__builtin_ia32_cvtps2udq512_mask(A, (__v16si)(W), U, B)) @@ -4903,7 +4905,6 @@ extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtsepi64_epi32 (__m512i __A) { - __v8si __O; return (__m256i) __builtin_ia32_pmovsqd512_mask ((__v8di) __A, (__v8si) _mm256_undefined_si256 (), @@ -5556,7 +5557,7 @@ _mm512_inserti64x4 (__m512i __A, __m256i __B, const int __imm) (__v4di) __B, __imm, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -5651,7 +5652,7 @@ _mm512_maskz_insertf64x4 (__mmask8 __U, __m512d __A, __m256d __B, #define _mm512_inserti64x4(X, Y, C) \ ((__m512i) __builtin_ia32_inserti64x4_mask ((__v8di)(__m512i) (X), \ (__v4di)(__m256i) (Y), (int) (C), \ - (__v8di)(__m512i)_mm512_undefined_si512 (), \ + (__v8di)(__m512i)_mm512_undefined_epi32 (), \ (__mmask8)-1)) #define _mm512_mask_inserti64x4(W, U, X, Y, C) \ @@ -6177,7 +6178,7 @@ _mm512_permutex_epi64 (__m512i __X, const int __I) { return (__m512i) __builtin_ia32_permdi512_mask ((__v8di) __X, __I, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) (-1)); } @@ -6248,7 +6249,7 @@ _mm512_maskz_permutex_pd (__mmask8 __U, __m512d __X, const int __M) ((__m512i) __builtin_ia32_permdi512_mask ((__v8di)(__m512i)(X), \ (int)(I), \ (__v8di)(__m512i) \ - (_mm512_undefined_si512 ()),\ + (_mm512_undefined_epi32 ()),\ (__mmask8)(-1))) #define _mm512_maskz_permutex_epi64(M, X, I) \ @@ -6283,7 +6284,7 @@ _mm512_permutexvar_epi64 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_permvardi512_mask ((__v8di) __Y, (__v8di) __X, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -6316,7 +6317,7 @@ _mm512_permutexvar_epi32 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_permvarsi512_mask ((__v16si) __Y, (__v16si) __X, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -6891,7 +6892,7 @@ _mm512_rol_epi32 (__m512i __A, const int __B) { return (__m512i) __builtin_ia32_prold512_mask ((__v16si) __A, __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -6920,7 +6921,7 @@ _mm512_ror_epi32 (__m512i __A, int __B) { return (__m512i) __builtin_ia32_prord512_mask ((__v16si) __A, __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -6949,7 +6950,7 @@ _mm512_rol_epi64 (__m512i __A, const int __B) { return (__m512i) __builtin_ia32_prolq512_mask ((__v8di) __A, __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -6978,7 +6979,7 @@ _mm512_ror_epi64 (__m512i __A, int __B) { return (__m512i) __builtin_ia32_prorq512_mask ((__v8di) __A, __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -7005,7 +7006,7 @@ _mm512_maskz_ror_epi64 (__mmask8 __U, __m512i __A, int __B) #define _mm512_rol_epi32(A, B) \ ((__m512i)__builtin_ia32_prold512_mask ((__v16si)(__m512i)(A), \ (int)(B), \ - (__v16si)_mm512_undefined_si512 (), \ + (__v16si)_mm512_undefined_epi32 (), \ (__mmask16)(-1))) #define _mm512_mask_rol_epi32(W, U, A, B) \ ((__m512i)__builtin_ia32_prold512_mask ((__v16si)(__m512i)(A), \ @@ -7020,7 +7021,7 @@ _mm512_maskz_ror_epi64 (__mmask8 __U, __m512i __A, int __B) #define _mm512_ror_epi32(A, B) \ ((__m512i)__builtin_ia32_prord512_mask ((__v16si)(__m512i)(A), \ (int)(B), \ - (__v16si)_mm512_undefined_si512 (), \ + (__v16si)_mm512_undefined_epi32 (), \ (__mmask16)(-1))) #define _mm512_mask_ror_epi32(W, U, A, B) \ ((__m512i)__builtin_ia32_prord512_mask ((__v16si)(__m512i)(A), \ @@ -7035,7 +7036,7 @@ _mm512_maskz_ror_epi64 (__mmask8 __U, __m512i __A, int __B) #define _mm512_rol_epi64(A, B) \ ((__m512i)__builtin_ia32_prolq512_mask ((__v8di)(__m512i)(A), \ (int)(B), \ - (__v8di)_mm512_undefined_si512 (), \ + (__v8di)_mm512_undefined_epi32 (), \ (__mmask8)(-1))) #define _mm512_mask_rol_epi64(W, U, A, B) \ ((__m512i)__builtin_ia32_prolq512_mask ((__v8di)(__m512i)(A), \ @@ -7051,7 +7052,7 @@ _mm512_maskz_ror_epi64 (__mmask8 __U, __m512i __A, int __B) #define _mm512_ror_epi64(A, B) \ ((__m512i)__builtin_ia32_prorq512_mask ((__v8di)(__m512i)(A), \ (int)(B), \ - (__v8di)_mm512_undefined_si512 (), \ + (__v8di)_mm512_undefined_epi32 (), \ (__mmask8)(-1))) #define _mm512_mask_ror_epi64(W, U, A, B) \ ((__m512i)__builtin_ia32_prorq512_mask ((__v8di)(__m512i)(A), \ @@ -7134,7 +7135,7 @@ _mm512_andnot_si512 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pandnd512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -7145,7 +7146,7 @@ _mm512_andnot_epi32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pandnd512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -7177,7 +7178,7 @@ _mm512_andnot_epi64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pandnq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -7275,7 +7276,7 @@ _mm512_unpackhi_epi32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_punpckhdq512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -7308,7 +7309,7 @@ _mm512_unpackhi_epi64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_punpckhqdq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -7340,7 +7341,7 @@ _mm512_unpacklo_epi32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_punpckldq512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -7373,7 +7374,7 @@ _mm512_unpacklo_epi64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_punpcklqdq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -8512,7 +8513,7 @@ _mm512_alignr_epi32 (__m512i __A, __m512i __B, const int __imm) return (__m512i) __builtin_ia32_alignd512_mask ((__v16si) __A, (__v16si) __B, __imm, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -8546,7 +8547,7 @@ _mm512_alignr_epi64 (__m512i __A, __m512i __B, const int __imm) return (__m512i) __builtin_ia32_alignq512_mask ((__v8di) __A, (__v8di) __B, __imm, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -8575,7 +8576,7 @@ _mm512_maskz_alignr_epi64 (__mmask8 __U, __m512i __A, __m512i __B, #else #define _mm512_alignr_epi32(X, Y, C) \ ((__m512i)__builtin_ia32_alignd512_mask ((__v16si)(__m512i)(X), \ - (__v16si)(__m512i)(Y), (int)(C), (__v16si)_mm512_undefined_si512 (),\ + (__v16si)(__m512i)(Y), (int)(C), (__v16si)_mm512_undefined_epi32 (),\ (__mmask16)-1)) #define _mm512_mask_alignr_epi32(W, U, X, Y, C) \ @@ -8590,7 +8591,7 @@ _mm512_maskz_alignr_epi64 (__mmask8 __U, __m512i __A, __m512i __B, #define _mm512_alignr_epi64(X, Y, C) \ ((__m512i)__builtin_ia32_alignq512_mask ((__v8di)(__m512i)(X), \ - (__v8di)(__m512i)(Y), (int)(C), (__v8di)_mm512_undefined_si512 (), \ + (__v8di)(__m512i)(Y), (int)(C), (__v8di)_mm512_undefined_epi32 (), \ (__mmask8)-1)) #define _mm512_mask_alignr_epi64(W, U, X, Y, C) \ @@ -9130,9 +9131,9 @@ _mm_mask_cmp_round_ss_mask (__mmask8 __M, __m128 __X, __m128 __Y, (__mmask8)-1)) #define _mm512_cmp_epi32_mask(X, Y, P) \ - ((__mmask8) __builtin_ia32_cmpd512_mask ((__v16si)(__m512i)(X), \ - (__v16si)(__m512i)(Y), (int)(P),\ - (__mmask16)-1)) + ((__mmask16) __builtin_ia32_cmpd512_mask ((__v16si)(__m512i)(X), \ + (__v16si)(__m512i)(Y), (int)(P), \ + (__mmask16)-1)) #define _mm512_cmp_epu64_mask(X, Y, P) \ ((__mmask8) __builtin_ia32_ucmpq512_mask ((__v8di)(__m512i)(X), \ @@ -9140,66 +9141,66 @@ _mm_mask_cmp_round_ss_mask (__mmask8 __M, __m128 __X, __m128 __Y, (__mmask8)-1)) #define _mm512_cmp_epu32_mask(X, Y, P) \ - ((__mmask8) __builtin_ia32_ucmpd512_mask ((__v16si)(__m512i)(X), \ - (__v16si)(__m512i)(Y), (int)(P),\ - (__mmask16)-1)) + ((__mmask16) __builtin_ia32_ucmpd512_mask ((__v16si)(__m512i)(X), \ + (__v16si)(__m512i)(Y), (int)(P), \ + (__mmask16)-1)) -#define _mm512_cmp_round_pd_mask(X, Y, P, R) \ +#define _mm512_cmp_round_pd_mask(X, Y, P, R) \ ((__mmask8) __builtin_ia32_cmppd512_mask ((__v8df)(__m512d)(X), \ (__v8df)(__m512d)(Y), (int)(P),\ (__mmask8)-1, R)) -#define _mm512_cmp_round_ps_mask(X, Y, P, R) \ +#define _mm512_cmp_round_ps_mask(X, Y, P, R) \ ((__mmask16) __builtin_ia32_cmpps512_mask ((__v16sf)(__m512)(X), \ (__v16sf)(__m512)(Y), (int)(P),\ (__mmask16)-1, R)) -#define _mm512_mask_cmp_epi64_mask(M, X, Y, P) \ +#define _mm512_mask_cmp_epi64_mask(M, X, Y, P) \ ((__mmask8) __builtin_ia32_cmpq512_mask ((__v8di)(__m512i)(X), \ (__v8di)(__m512i)(Y), (int)(P),\ (__mmask8)M)) -#define _mm512_mask_cmp_epi32_mask(M, X, Y, P) \ - ((__mmask8) __builtin_ia32_cmpd512_mask ((__v16si)(__m512i)(X), \ - (__v16si)(__m512i)(Y), (int)(P),\ - (__mmask16)M)) +#define _mm512_mask_cmp_epi32_mask(M, X, Y, P) \ + ((__mmask16) __builtin_ia32_cmpd512_mask ((__v16si)(__m512i)(X), \ + (__v16si)(__m512i)(Y), (int)(P), \ + (__mmask16)M)) -#define _mm512_mask_cmp_epu64_mask(M, X, Y, P) \ +#define _mm512_mask_cmp_epu64_mask(M, X, Y, P) \ ((__mmask8) __builtin_ia32_ucmpq512_mask ((__v8di)(__m512i)(X), \ (__v8di)(__m512i)(Y), (int)(P),\ (__mmask8)M)) -#define _mm512_mask_cmp_epu32_mask(M, X, Y, P) \ - ((__mmask8) __builtin_ia32_ucmpd512_mask ((__v16si)(__m512i)(X), \ - (__v16si)(__m512i)(Y), (int)(P),\ - (__mmask16)M)) +#define _mm512_mask_cmp_epu32_mask(M, X, Y, P) \ + ((__mmask16) __builtin_ia32_ucmpd512_mask ((__v16si)(__m512i)(X), \ + (__v16si)(__m512i)(Y), (int)(P), \ + (__mmask16)M)) -#define _mm512_mask_cmp_round_pd_mask(M, X, Y, P, R) \ +#define _mm512_mask_cmp_round_pd_mask(M, X, Y, P, R) \ ((__mmask8) __builtin_ia32_cmppd512_mask ((__v8df)(__m512d)(X), \ (__v8df)(__m512d)(Y), (int)(P),\ (__mmask8)M, R)) -#define _mm512_mask_cmp_round_ps_mask(M, X, Y, P, R) \ +#define _mm512_mask_cmp_round_ps_mask(M, X, Y, P, R) \ ((__mmask16) __builtin_ia32_cmpps512_mask ((__v16sf)(__m512)(X), \ (__v16sf)(__m512)(Y), (int)(P),\ (__mmask16)M, R)) -#define _mm_cmp_round_sd_mask(X, Y, P, R) \ +#define _mm_cmp_round_sd_mask(X, Y, P, R) \ ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), \ (__v2df)(__m128d)(Y), (int)(P),\ (__mmask8)-1, R)) -#define _mm_mask_cmp_round_sd_mask(M, X, Y, P, R) \ +#define _mm_mask_cmp_round_sd_mask(M, X, Y, P, R) \ ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), \ (__v2df)(__m128d)(Y), (int)(P),\ (M), R)) -#define _mm_cmp_round_ss_mask(X, Y, P, R) \ +#define _mm_cmp_round_ss_mask(X, Y, P, R) \ ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), \ (__v4sf)(__m128)(Y), (int)(P), \ (__mmask8)-1, R)) -#define _mm_mask_cmp_round_ss_mask(M, X, Y, P, R) \ +#define _mm_mask_cmp_round_ss_mask(M, X, Y, P, R) \ ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), \ (__v4sf)(__m128)(Y), (int)(P), \ (M), R)) @@ -9306,7 +9307,7 @@ extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_i32gather_epi32 (__m512i __index, int const *__addr, int __scale) { - __m512i v1_old = _mm512_undefined_si512 (); + __m512i v1_old = _mm512_undefined_epi32 (); __mmask16 mask = 0xFFFF; return (__m512i) __builtin_ia32_gathersiv16si ((__v16si) v1_old, @@ -9330,7 +9331,7 @@ extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_i32gather_epi64 (__m256i __index, long long const *__addr, int __scale) { - __m512i v1_old = _mm512_undefined_si512 (); + __m512i v1_old = _mm512_undefined_epi32 (); __mmask8 mask = 0xFF; return (__m512i) __builtin_ia32_gathersiv8di ((__v8di) v1_old, @@ -9379,7 +9380,7 @@ extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_i64gather_epi64 (__m512i __index, long long const *__addr, int __scale) { - __m512i v1_old = _mm512_undefined_si512 (); + __m512i v1_old = _mm512_undefined_epi32 (); __mmask8 mask = 0xFF; return (__m512i) __builtin_ia32_gatherdiv8di ((__v8di) v1_old, @@ -9591,7 +9592,7 @@ _mm512_mask_i64scatter_epi64 (long long *__addr, __mmask8 __mask, (__mmask8)MASK, (int)SCALE) #define _mm512_i32gather_epi32(INDEX, ADDR, SCALE) \ - (__m512i) __builtin_ia32_gathersiv16si ((__v16si)_mm512_undefined_si512 (), \ + (__m512i) __builtin_ia32_gathersiv16si ((__v16si)_mm512_undefined_epi32 (), \ (int const *)ADDR, \ (__v16si)(__m512i)INDEX, \ (__mmask16)0xFFFF, (int)SCALE) @@ -9603,7 +9604,7 @@ _mm512_mask_i64scatter_epi64 (long long *__addr, __mmask8 __mask, (__mmask16)MASK, (int)SCALE) #define _mm512_i32gather_epi64(INDEX, ADDR, SCALE) \ - (__m512i) __builtin_ia32_gathersiv8di ((__v8di)_mm512_undefined_si512 (), \ + (__m512i) __builtin_ia32_gathersiv8di ((__v8di)_mm512_undefined_epi32 (), \ (long long const *)ADDR, \ (__v8si)(__m256i)INDEX, \ (__mmask8)0xFF, (int)SCALE) @@ -9627,7 +9628,7 @@ _mm512_mask_i64scatter_epi64 (long long *__addr, __mmask8 __mask, (__mmask8)MASK, (int)SCALE) #define _mm512_i64gather_epi64(INDEX, ADDR, SCALE) \ - (__m512i) __builtin_ia32_gatherdiv8di ((__v8di)_mm512_undefined_si512 (), \ + (__m512i) __builtin_ia32_gatherdiv8di ((__v8di)_mm512_undefined_epi32 (), \ (long long const *)ADDR, \ (__v8di)(__m512i)INDEX, \ (__mmask8)0xFF, (int)SCALE) @@ -10123,7 +10124,7 @@ _mm512_max_epi64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pmaxsq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -10154,7 +10155,7 @@ _mm512_min_epi64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pminsq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -10185,7 +10186,7 @@ _mm512_max_epu64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pmaxuq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -10216,7 +10217,7 @@ _mm512_min_epu64 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pminuq512_mask ((__v8di) __A, (__v8di) __B, (__v8di) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask8) -1); } @@ -10247,7 +10248,7 @@ _mm512_max_epi32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pmaxsd512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -10278,7 +10279,7 @@ _mm512_min_epi32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pminsd512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -10309,7 +10310,7 @@ _mm512_max_epu32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pmaxud512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -10340,7 +10341,7 @@ _mm512_min_epu32 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_pminud512_mask ((__v16si) __A, (__v16si) __B, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1); } @@ -11804,7 +11805,7 @@ _mm512_cvttps_epi32 (__m512 __A) { return (__m512i) __builtin_ia32_cvttps2dq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, _MM_FROUND_CUR_DIRECTION); } @@ -11836,7 +11837,7 @@ _mm512_cvttps_epu32 (__m512 __A) { return (__m512i) __builtin_ia32_cvttps2udq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, _MM_FROUND_CUR_DIRECTION); } @@ -11868,7 +11869,7 @@ _mm512_cvtps_epi32 (__m512 __A) { return (__m512i) __builtin_ia32_cvtps2dq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, _MM_FROUND_CUR_DIRECTION); } @@ -11900,7 +11901,7 @@ _mm512_cvtps_epu32 (__m512 __A) { return (__m512i) __builtin_ia32_cvtps2udq512_mask ((__v16sf) __A, (__v16si) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask16) -1, _MM_FROUND_CUR_DIRECTION); } diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512ifmaintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512ifmaintrin.h index b558981b25..281aa64f27 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512ifmaintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512ifmaintrin.h @@ -41,7 +41,7 @@ _mm512_madd52lo_epu64 (__m512i __X, __m512i __Y, __m512i __Z) return (__m512i) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X, (__v8di) __Y, (__v8di) __Z, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __m512i @@ -51,7 +51,7 @@ _mm512_madd52hi_epu64 (__m512i __X, __m512i __Y, __m512i __Z) return (__m512i) __builtin_ia32_vpmadd52huq512_mask ((__v8di) __X, (__v8di) __Y, (__v8di) __Z, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __m512i diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512ifmavlintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512ifmavlintrin.h index 750eaff3ed..ac37646eba 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512ifmavlintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512ifmavlintrin.h @@ -41,7 +41,7 @@ _mm_madd52lo_epu64 (__m128i __X, __m128i __Y, __m128i __Z) return (__m128i) __builtin_ia32_vpmadd52luq128_mask ((__v2di) __X, (__v2di) __Y, (__v2di) __Z, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __m128i @@ -51,7 +51,7 @@ _mm_madd52hi_epu64 (__m128i __X, __m128i __Y, __m128i __Z) return (__m128i) __builtin_ia32_vpmadd52huq128_mask ((__v2di) __X, (__v2di) __Y, (__v2di) __Z, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __m256i @@ -61,7 +61,7 @@ _mm256_madd52lo_epu64 (__m256i __X, __m256i __Y, __m256i __Z) return (__m256i) __builtin_ia32_vpmadd52luq256_mask ((__v4di) __X, (__v4di) __Y, (__v4di) __Z, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __m256i @@ -71,7 +71,7 @@ _mm256_madd52hi_epu64 (__m256i __X, __m256i __Y, __m256i __Z) return (__m256i) __builtin_ia32_vpmadd52huq256_mask ((__v4di) __X, (__v4di) __Y, (__v4di) __Z, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __m128i diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512vbmiintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512vbmiintrin.h index f93b13b47d..7a14865dfb 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512vbmiintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512vbmiintrin.h @@ -62,7 +62,7 @@ _mm512_multishift_epi64_epi8 (__m512i __X, __m512i __Y) return (__m512i) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X, (__v64qi) __Y, (__v64qi) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask64) -1); } @@ -73,7 +73,7 @@ _mm512_permutexvar_epi8 (__m512i __A, __m512i __B) return (__m512i) __builtin_ia32_permvarqi512_mask ((__v64qi) __B, (__v64qi) __A, (__v64qi) - _mm512_undefined_si512 (), + _mm512_undefined_epi32 (), (__mmask64) -1); } @@ -108,8 +108,7 @@ _mm512_permutex2var_epi8 (__m512i __A, __m512i __I, __m512i __B) /* idx */ , (__v64qi) __A, (__v64qi) __B, - (__mmask64) - - 1); + (__mmask64) -1); } extern __inline __m512i diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512vbmivlintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512vbmivlintrin.h index cab4e5c07c..f7af20e708 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512vbmivlintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512vbmivlintrin.h @@ -173,8 +173,7 @@ _mm256_permutex2var_epi8 (__m256i __A, __m256i __I, __m256i __B) /* idx */ , (__v32qi) __A, (__v32qi) __B, - (__mmask32) - - 1); + (__mmask32) -1); } extern __inline __m256i @@ -224,8 +223,7 @@ _mm_permutex2var_epi8 (__m128i __A, __m128i __I, __m128i __B) /* idx */ , (__v16qi) __A, (__v16qi) __B, - (__mmask16) - - 1); + (__mmask16) -1); } extern __inline __m128i diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512vlbwintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512vlbwintrin.h index 601dcdd91a..9423101a90 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512vlbwintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512vlbwintrin.h @@ -575,8 +575,7 @@ _mm256_permutex2var_epi16 (__m256i __A, __m256i __I, __m256i __B) /* idx */ , (__v16hi) __A, (__v16hi) __B, - (__mmask16) - - 1); + (__mmask16) -1); } extern __inline __m256i @@ -626,8 +625,7 @@ _mm_permutex2var_epi16 (__m128i __A, __m128i __I, __m128i __B) /* idx */ , (__v8hi) __A, (__v8hi) __B, - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128i @@ -2009,7 +2007,7 @@ _mm256_cmpneq_epi8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 4, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2018,7 +2016,7 @@ _mm256_cmplt_epi8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 1, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2027,7 +2025,7 @@ _mm256_cmpge_epi8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 5, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -2036,7 +2034,7 @@ _mm256_cmple_epi8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 2, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask16 @@ -2045,7 +2043,7 @@ _mm256_cmpneq_epi16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 4, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2054,7 +2052,7 @@ _mm256_cmplt_epi16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 1, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2063,7 +2061,7 @@ _mm256_cmpge_epi16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 5, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2072,7 +2070,7 @@ _mm256_cmple_epi16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 2, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2081,7 +2079,7 @@ _mm_cmpneq_epu8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_ucmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 4, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2090,7 +2088,7 @@ _mm_cmplt_epu8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_ucmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 1, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2099,7 +2097,7 @@ _mm_cmpge_epu8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_ucmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 5, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2108,7 +2106,7 @@ _mm_cmple_epu8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_ucmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 2, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask8 @@ -2117,7 +2115,7 @@ _mm_cmpneq_epu16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -2126,7 +2124,7 @@ _mm_cmplt_epu16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -2135,7 +2133,7 @@ _mm_cmpge_epu16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -2144,7 +2142,7 @@ _mm_cmple_epu16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask16 @@ -2153,7 +2151,7 @@ _mm_cmpneq_epi8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 4, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2162,7 +2160,7 @@ _mm_cmplt_epi8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 1, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2171,7 +2169,7 @@ _mm_cmpge_epi8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 5, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -2180,7 +2178,7 @@ _mm_cmple_epi8_mask (__m128i __X, __m128i __Y) { return (__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi) __X, (__v16qi) __Y, 2, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask8 @@ -2189,7 +2187,7 @@ _mm_cmpneq_epi16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -2198,7 +2196,7 @@ _mm_cmplt_epi16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -2207,7 +2205,7 @@ _mm_cmpge_epi16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -2216,7 +2214,7 @@ _mm_cmple_epi16_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpw128_mask ((__v8hi) __X, (__v8hi) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __m256i @@ -3609,7 +3607,7 @@ _mm256_cmpneq_epu8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 4, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -3618,7 +3616,7 @@ _mm256_cmplt_epu8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 1, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -3627,7 +3625,7 @@ _mm256_cmpge_epu8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 5, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask32 @@ -3636,7 +3634,7 @@ _mm256_cmple_epu8_mask (__m256i __X, __m256i __Y) { return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, (__v32qi) __Y, 2, - (__mmask32) - 1); + (__mmask32) -1); } extern __inline __mmask16 @@ -3645,7 +3643,7 @@ _mm256_cmpneq_epu16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 4, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -3654,7 +3652,7 @@ _mm256_cmplt_epu16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 1, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -3663,7 +3661,7 @@ _mm256_cmpge_epu16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 5, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline __mmask16 @@ -3672,7 +3670,7 @@ _mm256_cmple_epu16_mask (__m256i __X, __m256i __Y) { return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, (__v16hi) __Y, 2, - (__mmask16) - 1); + (__mmask16) -1); } extern __inline void diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512vldqintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512vldqintrin.h index 7ccb62b45c..56e8513c78 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512vldqintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512vldqintrin.h @@ -389,8 +389,7 @@ _mm256_broadcast_f64x2 (__m128d __A) return (__m256d) __builtin_ia32_broadcastf64x2_256_mask ((__v2df) __A, (__v4df)_mm256_undefined_pd(), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256d @@ -421,8 +420,7 @@ _mm256_broadcast_i64x2 (__m128i __A) return (__m256i) __builtin_ia32_broadcasti64x2_256_mask ((__v2di) __A, (__v4di)_mm256_undefined_si256(), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256i @@ -452,8 +450,7 @@ _mm256_broadcast_f32x2 (__m128 __A) { return (__m256) __builtin_ia32_broadcastf32x2_256_mask ((__v4sf) __A, (__v8sf)_mm256_undefined_ps(), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256 @@ -482,8 +479,7 @@ _mm256_broadcast_i32x2 (__m128i __A) return (__m256i) __builtin_ia32_broadcasti32x2_256_mask ((__v4si) __A, (__v8si)_mm256_undefined_si256(), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256i @@ -514,8 +510,7 @@ _mm_broadcast_i32x2 (__m128i __A) return (__m128i) __builtin_ia32_broadcasti32x2_128_mask ((__v4si) __A, (__v4si)_mm_undefined_si128(), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128i @@ -1351,8 +1346,7 @@ _mm256_extractf64x2_pd (__m256d __A, const int __imm) __imm, (__v2df) _mm_setzero_pd (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128d @@ -1388,8 +1382,7 @@ _mm256_extracti64x2_epi64 (__m256i __A, const int __imm) __imm, (__v2di) _mm_setzero_di (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128i @@ -1743,8 +1736,7 @@ _mm256_inserti64x2 (__m256i __A, __m128i __B, const int __imm) __imm, (__v4di) _mm256_setzero_si256 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256i @@ -1783,8 +1775,7 @@ _mm256_insertf64x2 (__m256d __A, __m128d __B, const int __imm) __imm, (__v4df) _mm256_setzero_pd (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256d diff --git a/contrib/gcc-5.0/gcc/config/i386/avx512vlintrin.h b/contrib/gcc-5.0/gcc/config/i386/avx512vlintrin.h index b995cecc8c..36771f6ffe 100644 --- a/contrib/gcc-5.0/gcc/config/i386/avx512vlintrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/avx512vlintrin.h @@ -2698,8 +2698,7 @@ _mm256_broadcast_f32x4 (__m128 __A) { return (__m256) __builtin_ia32_broadcastf32x4_256_mask ((__v4sf) __A, (__v8sf)_mm256_undefined_pd (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256 @@ -2728,8 +2727,7 @@ _mm256_broadcast_i32x4 (__m128i __A) return (__m256i) __builtin_ia32_broadcasti32x4_256_mask ((__v4si) __A, (__v8si)_mm256_undefined_si256 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256i @@ -6293,8 +6291,7 @@ _mm256_permutex2var_pd (__m256d __A, __m256i __I, __m256d __B) /* idx */ , (__v4df) __A, (__v4df) __B, - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256d @@ -6584,8 +6581,7 @@ _mm_permutex2var_pd (__m128d __A, __m128i __I, __m128d __B) /* idx */ , (__v2df) __A, (__v2df) __B, - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128d @@ -8259,8 +8255,7 @@ _mm256_conflict_epi64 (__m256i __A) return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A, (__v4di) _mm256_setzero_si256 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256i @@ -8291,8 +8286,7 @@ _mm256_conflict_epi32 (__m256i __A) return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A, (__v8si) _mm256_setzero_si256 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256i @@ -8381,8 +8375,7 @@ _mm_conflict_epi64 (__m128i __A) return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A, (__v2di) _mm_setzero_di (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128i @@ -8413,8 +8406,7 @@ _mm_conflict_epi32 (__m128i __A) return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A, (__v4si) _mm_setzero_si128 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128i @@ -9291,8 +9283,7 @@ _mm256_inserti32x4 (__m256i __A, __m128i __B, const int __imm) __imm, (__v8si) _mm256_setzero_si256 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m256i @@ -9367,8 +9358,7 @@ _mm256_extracti32x4_epi32 (__m256i __A, const int __imm) __imm, (__v4si) _mm_setzero_si128 (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128i @@ -9404,8 +9394,7 @@ _mm256_extractf32x4_ps (__m256 __A, const int __imm) __imm, (__v4sf) _mm_setzero_ps (), - (__mmask8) - - 1); + (__mmask8) -1); } extern __inline __m128 @@ -11797,7 +11786,7 @@ _mm256_cmpneq_epu32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpd256_mask ((__v8si) __X, (__v8si) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11815,7 +11804,7 @@ _mm256_cmplt_epu32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpd256_mask ((__v8si) __X, (__v8si) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11833,7 +11822,7 @@ _mm256_cmpge_epu32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpd256_mask ((__v8si) __X, (__v8si) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11851,7 +11840,7 @@ _mm256_cmple_epu32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpd256_mask ((__v8si) __X, (__v8si) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11869,7 +11858,7 @@ _mm256_cmpneq_epu64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpq256_mask ((__v4di) __X, (__v4di) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11887,7 +11876,7 @@ _mm256_cmplt_epu64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpq256_mask ((__v4di) __X, (__v4di) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11905,7 +11894,7 @@ _mm256_cmpge_epu64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpq256_mask ((__v4di) __X, (__v4di) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11923,7 +11912,7 @@ _mm256_cmple_epu64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_ucmpq256_mask ((__v4di) __X, (__v4di) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11941,7 +11930,7 @@ _mm256_cmpneq_epi32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpd256_mask ((__v8si) __X, (__v8si) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11959,7 +11948,7 @@ _mm256_cmplt_epi32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpd256_mask ((__v8si) __X, (__v8si) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11977,7 +11966,7 @@ _mm256_cmpge_epi32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpd256_mask ((__v8si) __X, (__v8si) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -11995,7 +11984,7 @@ _mm256_cmple_epi32_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpd256_mask ((__v8si) __X, (__v8si) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12013,7 +12002,7 @@ _mm256_cmpneq_epi64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpq256_mask ((__v4di) __X, (__v4di) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12031,7 +12020,7 @@ _mm256_cmplt_epi64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpq256_mask ((__v4di) __X, (__v4di) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12049,7 +12038,7 @@ _mm256_cmpge_epi64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpq256_mask ((__v4di) __X, (__v4di) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12067,7 +12056,7 @@ _mm256_cmple_epi64_mask (__m256i __X, __m256i __Y) { return (__mmask8) __builtin_ia32_cmpq256_mask ((__v4di) __X, (__v4di) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12085,7 +12074,7 @@ _mm_cmpneq_epu32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpd128_mask ((__v4si) __X, (__v4si) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12103,7 +12092,7 @@ _mm_cmplt_epu32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpd128_mask ((__v4si) __X, (__v4si) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12121,7 +12110,7 @@ _mm_cmpge_epu32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpd128_mask ((__v4si) __X, (__v4si) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12139,7 +12128,7 @@ _mm_cmple_epu32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpd128_mask ((__v4si) __X, (__v4si) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12157,7 +12146,7 @@ _mm_cmpneq_epu64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpq128_mask ((__v2di) __X, (__v2di) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12175,7 +12164,7 @@ _mm_cmplt_epu64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpq128_mask ((__v2di) __X, (__v2di) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12193,7 +12182,7 @@ _mm_cmpge_epu64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpq128_mask ((__v2di) __X, (__v2di) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12211,7 +12200,7 @@ _mm_cmple_epu64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_ucmpq128_mask ((__v2di) __X, (__v2di) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12229,7 +12218,7 @@ _mm_cmpneq_epi32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpd128_mask ((__v4si) __X, (__v4si) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12247,7 +12236,7 @@ _mm_cmplt_epi32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpd128_mask ((__v4si) __X, (__v4si) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12265,7 +12254,7 @@ _mm_cmpge_epi32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpd128_mask ((__v4si) __X, (__v4si) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12283,7 +12272,7 @@ _mm_cmple_epi32_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpd128_mask ((__v4si) __X, (__v4si) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12301,7 +12290,7 @@ _mm_cmpneq_epi64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpq128_mask ((__v2di) __X, (__v2di) __Y, 4, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12319,7 +12308,7 @@ _mm_cmplt_epi64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpq128_mask ((__v2di) __X, (__v2di) __Y, 1, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12337,7 +12326,7 @@ _mm_cmpge_epi64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpq128_mask ((__v2di) __X, (__v2di) __Y, 5, - (__mmask8) - 1); + (__mmask8) -1); } extern __inline __mmask8 @@ -12355,7 +12344,7 @@ _mm_cmple_epi64_mask (__m128i __X, __m128i __Y) { return (__mmask8) __builtin_ia32_cmpq128_mask ((__v2di) __X, (__v2di) __Y, 2, - (__mmask8) - 1); + (__mmask8) -1); } #else diff --git a/contrib/gcc-5.0/gcc/config/i386/constraints.md b/contrib/gcc-5.0/gcc/config/i386/constraints.md index 2271bd168e..f4a05a7092 100644 --- a/contrib/gcc-5.0/gcc/config/i386/constraints.md +++ b/contrib/gcc-5.0/gcc/config/i386/constraints.md @@ -141,14 +141,19 @@ "(ix86_fpmath & FPMATH_387) ? FLOAT_REGS : NO_REGS" "@internal Any x87 register when 80387 FP arithmetic is enabled.") +;; Yr constraint is meant to be used in noavx contexts only, for VEX and EVEX +;; the lower register numbers need the same instruction sizes as any other. +;; In case Yr constraint is misused, try to limit the damage, by treating +;; it as x constraint in avx mode, not v constraint. (define_register_constraint "Yr" - "TARGET_SSE ? (X86_TUNE_AVOID_4BYTE_PREFIXES ? NO_REX_SSE_REGS : ALL_SSE_REGS) : NO_REGS" + "TARGET_SSE ? ((TARGET_AVOID_4BYTE_PREFIXES && !TARGET_AVX) ? NO_REX_SSE_REGS : SSE_REGS) : NO_REGS" "@internal Lower SSE register when avoiding REX prefix and all SSE registers otherwise.") ;; We use the B prefix to denote any number of internal operands: ;; s Sibcall memory operand, not valid for TARGET_X32 ;; w Call memory operand, not valid for TARGET_X32 ;; z Constant call address operand. +;; C SSE constant operand. (define_constraint "Bs" "@internal Sibcall memory operand." @@ -164,6 +169,10 @@ "@internal Constant call address operand." (match_operand 0 "constant_call_address_operand")) +(define_constraint "BC" + "@internal SSE constant operand." + (match_test "standard_sse_constant_p (op)")) + ;; Integer constant constraints. (define_constraint "I" "Integer constant in the range 0 @dots{} 31, for 32-bit shifts." @@ -214,8 +223,8 @@ ;; This can theoretically be any mode's CONST0_RTX. (define_constraint "C" - "Standard SSE floating point constant." - (match_test "standard_sse_constant_p (op)")) + "SSE constant zero operand." + (match_test "standard_sse_constant_p (op) == 1")) ;; Constant-or-symbol-reference constraints. 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 1c6c22172d..c2cdb49ff6 100644 --- a/contrib/gcc-5.0/gcc/config/i386/driver-i386.c +++ b/contrib/gcc-5.0/gcc/config/i386/driver-i386.c @@ -630,33 +630,27 @@ const char *host_detect_local_cpu (int argc, const char **argv) } else if (vendor == signature_CENTAUR_ebx) { - if (arch) + processor = PROCESSOR_GENERIC; + + switch (family) { - switch (family) - { - case 6: - if (model > 9) - /* Use the default detection procedure. */ - processor = PROCESSOR_GENERIC; - else if (model == 9) - cpu = "c3-2"; - else if (model >= 6) - cpu = "c3"; - else - processor = PROCESSOR_GENERIC; - break; - case 5: - if (has_3dnow) - cpu = "winchip2"; - else if (has_mmx) - cpu = "winchip2-c6"; - else - processor = PROCESSOR_GENERIC; - break; - default: - /* We have no idea. */ - processor = PROCESSOR_GENERIC; - } + default: + /* We have no idea. */ + break; + + case 5: + if (has_3dnow || has_mmx) + processor = PROCESSOR_I486; + break; + + case 6: + if (model > 9 || has_longmode) + /* Use the default detection procedure. */ + ; + else if (model == 9) + processor = PROCESSOR_PENTIUMPRO; + else if (model >= 6) + processor = PROCESSOR_I486; } } else @@ -687,7 +681,18 @@ const char *host_detect_local_cpu (int argc, const char **argv) /* Default. */ break; case PROCESSOR_I486: - cpu = "i486"; + if (arch && vendor == signature_CENTAUR_ebx) + { + if (model >= 6) + cpu = "c3"; + else if (has_3dnow) + cpu = "winchip2"; + else + /* Assume WinChip C6. */ + cpu = "winchip-c6"; + } + else + cpu = "i486"; break; case PROCESSOR_PENTIUM: if (arch && has_mmx) @@ -804,8 +809,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) /* It is Pentium M. */ cpu = "pentium-m"; else if (has_sse) - /* It is Pentium III. */ - cpu = "pentium3"; + { + if (vendor == signature_CENTAUR_ebx) + cpu = "c3-2"; + else + /* It is Pentium III. */ + cpu = "pentium3"; + } else if (has_mmx) /* It is Pentium II. */ cpu = "pentium2"; @@ -886,6 +896,11 @@ const char *host_detect_local_cpu (int argc, const char **argv) else cpu = "prescott"; } + else if (has_longmode) + /* Perhaps some emulator? Assume x86-64, otherwise gcc + -march=native would be unusable for 64-bit compilations, + as all the CPUs below are 32-bit only. */ + cpu = "x86-64"; else if (has_sse2) cpu = "pentium4"; else if (has_cmov) diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.c b/contrib/gcc-5.0/gcc/config/i386/i386.c index 3b19caa413..4107d2ec80 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.c +++ b/contrib/gcc-5.0/gcc/config/i386/i386.c @@ -115,6 +115,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-iterator.h" #include "tree-chkp.h" #include "rtl-chkp.h" +#include "dojump.h" static rtx legitimize_dllimport_symbol (rtx, bool); static rtx legitimize_pe_coff_extern_decl (rtx, bool); @@ -562,17 +563,17 @@ struct processor_costs geode_cost = { {4, 6, 6}, /* cost of storing fp registers in SFmode, DFmode and XFmode */ - 1, /* cost of moving MMX register */ - {1, 1}, /* cost of loading MMX registers + 2, /* cost of moving MMX register */ + {2, 2}, /* cost of loading MMX registers in SImode and DImode */ - {1, 1}, /* cost of storing MMX registers + {2, 2}, /* cost of storing MMX registers in SImode and DImode */ - 1, /* cost of moving SSE register */ - {1, 1, 1}, /* cost of loading SSE registers + 2, /* cost of moving SSE register */ + {2, 2, 8}, /* cost of loading SSE registers in SImode, DImode and TImode */ - {1, 1, 1}, /* cost of storing SSE registers + {2, 2, 8}, /* cost of storing SSE registers in SImode, DImode and TImode */ - 1, /* MMX or SSE register to integer */ + 3, /* MMX or SSE register to integer */ 64, /* size of l1 cache. */ 128, /* size of l2 cache. */ 32, /* size of prefetch block */ @@ -4150,6 +4151,17 @@ ix86_option_override_internal (bool main_args_p, opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS; } + /* Stack realignment without -maccumulate-outgoing-args requires %ebp, + so enable -maccumulate-outgoing-args when %ebp is fixed. */ + if (fixed_regs[BP_REG] + && !(opts->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)) + { + if (opts_set->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS) + warning (0, "fixed ebp register requires %saccumulate-outgoing-args%s", + prefix, suffix); + opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS; + } + /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix. */ { char *p; @@ -4982,12 +4994,14 @@ ix86_valid_target_attribute_tree (tree args, /* If we are using the default tune= or arch=, undo the string assigned, and use the default. */ if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH]) - opts->x_ix86_arch_string = option_strings[IX86_FUNCTION_SPECIFIC_ARCH]; + opts->x_ix86_arch_string + = ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_ARCH]); else if (!orig_arch_specified) opts->x_ix86_arch_string = NULL; if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]) - opts->x_ix86_tune_string = option_strings[IX86_FUNCTION_SPECIFIC_TUNE]; + opts->x_ix86_tune_string + = ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]); else if (orig_tune_defaulted) opts->x_ix86_tune_string = NULL; @@ -6576,6 +6590,10 @@ type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum, { machine_mode innermode = TYPE_MODE (TREE_TYPE (type)); + /* There are no XFmode vector modes. */ + if (innermode == XFmode) + return mode; + if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) mode = MIN_MODE_VECTOR_FLOAT; else @@ -9677,6 +9695,10 @@ ix86_frame_pointer_required (void) if (TARGET_64BIT_MS_ABI && get_frame_size () > SEH_MAX_FRAME_SIZE) return true; + /* SSE saves require frame-pointer when stack is misaligned. */ + if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128) + return true; + /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER turns off the frame pointer by default. Turn it back on now if we've not got a leaf function. */ @@ -10114,18 +10136,6 @@ ix86_compute_frame_layout (struct ix86_frame *frame) crtl->preferred_stack_boundary = 128; crtl->stack_alignment_needed = 128; } - /* preferred_stack_boundary is never updated for call - expanded from tls descriptor. Update it here. We don't update it in - expand stage because according to the comments before - ix86_current_function_calls_tls_descriptor, tls calls may be optimized - away. */ - else if (ix86_current_function_calls_tls_descriptor - && crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY) - { - crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY; - if (crtl->stack_alignment_needed < PREFERRED_STACK_BOUNDARY) - crtl->stack_alignment_needed = PREFERRED_STACK_BOUNDARY; - } stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT; preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT; @@ -10799,6 +10809,11 @@ ix86_update_stack_boundary (void) && cfun->stdarg && crtl->stack_alignment_estimated < 128) crtl->stack_alignment_estimated = 128; + + /* __tls_get_addr needs to be called with 16-byte aligned stack. */ + if (ix86_tls_descriptor_calls_expanded_in_cfun + && crtl->preferred_stack_boundary < 128) + crtl->preferred_stack_boundary = 128; } /* Handle the TARGET_GET_DRAP_RTX hook. Return NULL if no DRAP is @@ -11258,10 +11273,11 @@ ix86_finalize_stack_realign_flags (void) unsigned int incoming_stack_boundary = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary); - unsigned int stack_realign = (incoming_stack_boundary - < (crtl->is_leaf - ? crtl->max_used_stack_slot_alignment - : crtl->stack_alignment_needed)); + unsigned int stack_realign + = (incoming_stack_boundary + < (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor + ? crtl->max_used_stack_slot_alignment + : crtl->stack_alignment_needed)); if (crtl->stack_realign_finalized) { @@ -17583,12 +17599,29 @@ ix86_expand_vector_move (machine_mode mode, rtx operands[]) of the register, once we have that information we may be able to handle some of them more efficiently. */ if (can_create_pseudo_p () - && register_operand (op0, mode) && (CONSTANT_P (op1) || (GET_CODE (op1) == SUBREG && CONSTANT_P (SUBREG_REG (op1)))) - && !standard_sse_constant_p (op1)) - op1 = validize_mem (force_const_mem (mode, op1)); + && ((register_operand (op0, mode) + && !standard_sse_constant_p (op1)) + /* ix86_expand_vector_move_misalign() does not like constants. */ + || (SSE_REG_MODE_P (mode) + && MEM_P (op0) + && MEM_ALIGN (op0) < align))) + { + if (SUBREG_P (op1)) + { + machine_mode imode = GET_MODE (SUBREG_REG (op1)); + rtx r = force_const_mem (imode, SUBREG_REG (op1)); + if (r) + r = validize_mem (r); + else + r = force_reg (imode, SUBREG_REG (op1)); + op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1)); + } + else + op1 = validize_mem (force_const_mem (mode, op1)); + } /* We need to check memory alignment for SSE mode since attribute can make operands unaligned. */ @@ -17599,13 +17632,8 @@ ix86_expand_vector_move (machine_mode mode, rtx operands[]) { rtx tmp[2]; - /* ix86_expand_vector_move_misalign() does not like constants ... */ - if (CONSTANT_P (op1) - || (GET_CODE (op1) == SUBREG - && CONSTANT_P (SUBREG_REG (op1)))) - op1 = validize_mem (force_const_mem (mode, op1)); - - /* ... nor both arguments in memory. */ + /* ix86_expand_vector_move_misalign() does not like both + arguments in memory. */ if (!register_operand (op0, mode) && !register_operand (op1, mode)) op1 = force_reg (mode, op1); @@ -17691,7 +17719,7 @@ ix86_avx256_split_vector_move_misalign (rtx op0, rtx op1) m = adjust_address (op0, mode, 0); emit_insn (extract (m, op1, const0_rtx)); m = adjust_address (op0, mode, 16); - emit_insn (extract (m, op1, const1_rtx)); + emit_insn (extract (m, copy_rtx (op1), const1_rtx)); } else emit_insn (store_unaligned (op0, op1)); @@ -17999,7 +18027,7 @@ ix86_expand_vector_move_misalign (machine_mode mode, rtx operands[]) m = adjust_address (op0, V2SFmode, 0); emit_insn (gen_sse_storelps (m, op1)); m = adjust_address (op0, V2SFmode, 8); - emit_insn (gen_sse_storehps (m, op1)); + emit_insn (gen_sse_storehps (m, copy_rtx (op1))); } } } @@ -24365,7 +24393,7 @@ expand_small_movmem_or_setmem (rtx destmem, rtx srcmem, if (DYNAMIC_CHECK) Round COUNT down to multiple of SIZE << optional caller supplied zero size guard is here >> - << optional caller suppplied dynamic check is here >> + << optional caller supplied dynamic check is here >> << caller supplied main copy loop is here >> } done_label: @@ -24539,8 +24567,8 @@ expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src else *min_size = 0; - /* Our loops always round down the bock size, but for dispatch to library - we need precise value. */ + /* Our loops always round down the block size, but for dispatch to + library we need precise value. */ if (dynamic_check) *count = expand_simple_binop (GET_MODE (*count), AND, *count, GEN_INT (-size), *count, 1, OPTAB_DIRECT); @@ -24659,9 +24687,10 @@ alg_usable_p (enum stringop_alg alg, bool memset) static enum stringop_alg decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, unsigned HOST_WIDE_INT min_size, unsigned HOST_WIDE_INT max_size, - bool memset, bool zero_memset, int *dynamic_check, bool *noalign) + bool memset, bool zero_memset, int *dynamic_check, bool *noalign, + bool recur) { - const struct stringop_algs * algs; + const struct stringop_algs *algs; bool optimize_for_speed; int max = 0; const struct processor_costs *cost; @@ -24695,7 +24724,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, any_alg_usable_p |= usable; if (candidate != libcall && candidate && usable) - max = algs->size[i].max; + max = algs->size[i].max; } /* If expected size is not known but max size is small enough @@ -24705,7 +24734,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, && expected_size == -1) expected_size = min_size / 2 + max_size / 2; - /* If user specified the algorithm, honnor it if possible. */ + /* If user specified the algorithm, honor it if possible. */ if (ix86_stringop_alg != no_stringop && alg_usable_p (ix86_stringop_alg, memset)) return ix86_stringop_alg; @@ -24780,21 +24809,20 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, || !alg_usable_p (algs->unknown_size, memset))) { enum stringop_alg alg; + HOST_WIDE_INT new_expected_size = (max > 0 ? max : 4096) / 2; - /* If there aren't any usable algorithms, then recursing on - smaller sizes isn't going to find anything. Just return the - simple byte-at-a-time copy loop. */ - if (!any_alg_usable_p) - { - /* Pick something reasonable. */ - if (TARGET_INLINE_STRINGOPS_DYNAMICALLY) - *dynamic_check = 128; - return loop_1_byte; - } - if (max <= 0) - max = 4096; - alg = decide_alg (count, max / 2, min_size, max_size, memset, - zero_memset, dynamic_check, noalign); + /* If there aren't any usable algorithms or if recursing already, + then recursing on smaller sizes or same size isn't going to + find anything. Just return the simple byte-at-a-time copy loop. */ + if (!any_alg_usable_p || recur) + { + /* Pick something reasonable. */ + if (TARGET_INLINE_STRINGOPS_DYNAMICALLY && !recur) + *dynamic_check = 128; + return loop_1_byte; + } + alg = decide_alg (count, new_expected_size, min_size, max_size, memset, + zero_memset, dynamic_check, noalign, true); gcc_assert (*dynamic_check == -1); if (TARGET_INLINE_STRINGOPS_DYNAMICALLY) *dynamic_check = max; @@ -25050,7 +25078,7 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp, alg = decide_alg (count, expected_size, min_size, probable_max_size, issetmem, issetmem && val_exp == const0_rtx, - &dynamic_check, &noalign); + &dynamic_check, &noalign, false); if (alg == libcall) return false; gcc_assert (alg != no_stringop); @@ -25118,6 +25146,13 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp, size_needed = GET_MODE_SIZE (move_mode) * unroll_factor; epilogue_size_needed = size_needed; + /* If we are going to call any library calls conditionally, make sure any + pending stack adjustment happen before the first conditional branch, + otherwise they will be emitted before the library call only and won't + happen from the other branches. */ + if (dynamic_check != -1) + do_pending_stack_adjust (); + desired_align = decide_alignment (align, alg, expected_size, move_mode); if (!TARGET_ALIGN_STRINGOPS || noalign) align = desired_align; @@ -30800,6 +30835,14 @@ def_builtin (HOST_WIDE_INT mask, const char *name, { ix86_builtins_isa[(int) code].isa = mask; + /* OPTION_MASK_ISA_AVX512VL has special meaning. Despite of generic case, + where any bit set means that built-in is enable, this bit must be *and-ed* + with another one. E.g.: OPTION_MASK_ISA_AVX512DQ | OPTION_MASK_ISA_AVX512VL + means that *both* cpuid bits must be set for the built-in to be available. + Handle this here. */ + if (mask & ix86_isa_flags & OPTION_MASK_ISA_AVX512VL) + mask &= ~OPTION_MASK_ISA_AVX512VL; + mask &= ~OPTION_MASK_ISA_64BIT; if (mask == 0 || (mask & ix86_isa_flags) != 0 @@ -31131,9 +31174,9 @@ static const struct builtin_description bdesc_special_args[] = { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_llwpcb, "__builtin_ia32_llwpcb", IX86_BUILTIN_LLWPCB, UNKNOWN, (int) VOID_FTYPE_PVOID }, { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_slwpcb, "__builtin_ia32_slwpcb", IX86_BUILTIN_SLWPCB, UNKNOWN, (int) PVOID_FTYPE_VOID }, { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpvalsi3, "__builtin_ia32_lwpval32", IX86_BUILTIN_LWPVAL32, UNKNOWN, (int) VOID_FTYPE_UINT_UINT_UINT }, - { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpvaldi3, "__builtin_ia32_lwpval64", IX86_BUILTIN_LWPVAL64, UNKNOWN, (int) VOID_FTYPE_UINT64_UINT_UINT }, + { OPTION_MASK_ISA_LWP | OPTION_MASK_ISA_64BIT, CODE_FOR_lwp_lwpvaldi3, "__builtin_ia32_lwpval64", IX86_BUILTIN_LWPVAL64, UNKNOWN, (int) VOID_FTYPE_UINT64_UINT_UINT }, { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinssi3, "__builtin_ia32_lwpins32", IX86_BUILTIN_LWPINS32, UNKNOWN, (int) UCHAR_FTYPE_UINT_UINT_UINT }, - { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinsdi3, "__builtin_ia32_lwpins64", IX86_BUILTIN_LWPINS64, UNKNOWN, (int) UCHAR_FTYPE_UINT64_UINT_UINT }, + { OPTION_MASK_ISA_LWP | OPTION_MASK_ISA_64BIT, CODE_FOR_lwp_lwpinsdi3, "__builtin_ia32_lwpins64", IX86_BUILTIN_LWPINS64, UNKNOWN, (int) UCHAR_FTYPE_UINT64_UINT_UINT }, /* FSGSBASE */ { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_rdfsbasesi, "__builtin_ia32_rdfsbase32", IX86_BUILTIN_RDFSBASE32, UNKNOWN, (int) UNSIGNED_FTYPE_VOID }, @@ -32064,12 +32107,12 @@ static const struct builtin_description bdesc_args[] = /* BMI */ { OPTION_MASK_ISA_BMI, CODE_FOR_bmi_bextr_si, "__builtin_ia32_bextr_u32", IX86_BUILTIN_BEXTR32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT }, - { OPTION_MASK_ISA_BMI, CODE_FOR_bmi_bextr_di, "__builtin_ia32_bextr_u64", IX86_BUILTIN_BEXTR64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, + { OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_64BIT, CODE_FOR_bmi_bextr_di, "__builtin_ia32_bextr_u64", IX86_BUILTIN_BEXTR64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, { OPTION_MASK_ISA_BMI, CODE_FOR_ctzhi2, "__builtin_ctzs", IX86_BUILTIN_CTZS, UNKNOWN, (int) UINT16_FTYPE_UINT16 }, /* TBM */ { OPTION_MASK_ISA_TBM, CODE_FOR_tbm_bextri_si, "__builtin_ia32_bextri_u32", IX86_BUILTIN_BEXTRI32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT }, - { OPTION_MASK_ISA_TBM, CODE_FOR_tbm_bextri_di, "__builtin_ia32_bextri_u64", IX86_BUILTIN_BEXTRI64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, + { OPTION_MASK_ISA_TBM | OPTION_MASK_ISA_64BIT, CODE_FOR_tbm_bextri_di, "__builtin_ia32_bextri_u64", IX86_BUILTIN_BEXTRI64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, /* F16C */ { OPTION_MASK_ISA_F16C, CODE_FOR_vcvtph2ps, "__builtin_ia32_vcvtph2ps", IX86_BUILTIN_CVTPH2PS, UNKNOWN, (int) V4SF_FTYPE_V8HI }, @@ -32079,11 +32122,11 @@ static const struct builtin_description bdesc_args[] = /* BMI2 */ { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_bzhi_si3, "__builtin_ia32_bzhi_si", IX86_BUILTIN_BZHI32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT }, - { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_bzhi_di3, "__builtin_ia32_bzhi_di", IX86_BUILTIN_BZHI64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, + { OPTION_MASK_ISA_BMI2 | OPTION_MASK_ISA_64BIT, CODE_FOR_bmi2_bzhi_di3, "__builtin_ia32_bzhi_di", IX86_BUILTIN_BZHI64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pdep_si3, "__builtin_ia32_pdep_si", IX86_BUILTIN_PDEP32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT }, - { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pdep_di3, "__builtin_ia32_pdep_di", IX86_BUILTIN_PDEP64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, + { OPTION_MASK_ISA_BMI2 | OPTION_MASK_ISA_64BIT, CODE_FOR_bmi2_pdep_di3, "__builtin_ia32_pdep_di", IX86_BUILTIN_PDEP64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pext_si3, "__builtin_ia32_pext_si", IX86_BUILTIN_PEXT32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT }, - { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pext_di3, "__builtin_ia32_pext_di", IX86_BUILTIN_PEXT64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, + { OPTION_MASK_ISA_BMI2 | OPTION_MASK_ISA_64BIT, CODE_FOR_bmi2_pext_di3, "__builtin_ia32_pext_di", IX86_BUILTIN_PEXT64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, /* AVX512F */ { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_si512_256si, "__builtin_ia32_si512_256si", IX86_BUILTIN_SI512_SI256, UNKNOWN, (int) V16SI_FTYPE_V8SI }, @@ -32461,9 +32504,9 @@ static const struct builtin_description bdesc_args[] = { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_permvarv16hi_mask, "__builtin_ia32_permvarhi256_mask", IX86_BUILTIN_VPERMVARHI256_MASK, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_HI }, { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_permvarv8hi_mask, "__builtin_ia32_permvarhi128_mask", IX86_BUILTIN_VPERMVARHI128_MASK, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_QI }, { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv16hi3_mask, "__builtin_ia32_vpermt2varhi256_mask", IX86_BUILTIN_VPERMT2VARHI256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_HI }, - { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv16hi3_maskz, "__builtin_ia32_vpermt2varhi256_maskz", IX86_BUILTIN_VPERMT2VARHI256_MASKZ, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_HI }, + { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv16hi3_maskz, "__builtin_ia32_vpermt2varhi256_maskz", IX86_BUILTIN_VPERMT2VARHI256_MASKZ, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_HI }, { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv8hi3_mask, "__builtin_ia32_vpermt2varhi128_mask", IX86_BUILTIN_VPERMT2VARHI128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_QI }, - { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv8hi3_maskz, "__builtin_ia32_vpermt2varhi128_maskz", IX86_BUILTIN_VPERMT2VARHI128_MASKZ, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_QI }, + { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv8hi3_maskz, "__builtin_ia32_vpermt2varhi128_maskz", IX86_BUILTIN_VPERMT2VARHI128_MASKZ, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_QI }, { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermi2varv16hi3_mask, "__builtin_ia32_vpermi2varhi256_mask", IX86_BUILTIN_VPERMI2VARHI256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_HI }, { OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermi2varv8hi3_mask, "__builtin_ia32_vpermi2varhi128_mask", IX86_BUILTIN_VPERMI2VARHI128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_QI }, { OPTION_MASK_ISA_AVX512VL, CODE_FOR_rcp14v4df_mask, "__builtin_ia32_rcp14pd256_mask", IX86_BUILTIN_RCP14PD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_QI }, @@ -33178,9 +33221,9 @@ static const struct builtin_description bdesc_args[] = { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_permvarv32qi_mask, "__builtin_ia32_permvarqi256_mask", IX86_BUILTIN_VPERMVARQI256_MASK, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI_SI }, { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_permvarv16qi_mask, "__builtin_ia32_permvarqi128_mask", IX86_BUILTIN_VPERMVARQI128_MASK, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI_HI }, { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv32qi3_mask, "__builtin_ia32_vpermt2varqi256_mask", IX86_BUILTIN_VPERMT2VARQI256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI_SI }, - { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv32qi3_maskz, "__builtin_ia32_vpermt2varqi256_maskz", IX86_BUILTIN_VPERMT2VARQI256_MASKZ, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI_SI }, + { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv32qi3_maskz, "__builtin_ia32_vpermt2varqi256_maskz", IX86_BUILTIN_VPERMT2VARQI256_MASKZ, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI_SI }, { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv16qi3_mask, "__builtin_ia32_vpermt2varqi128_mask", IX86_BUILTIN_VPERMT2VARQI128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI_HI }, - { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv16qi3_maskz, "__builtin_ia32_vpermt2varqi128_maskz", IX86_BUILTIN_VPERMT2VARQI128_MASKZ, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI_HI }, + { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermt2varv16qi3_maskz, "__builtin_ia32_vpermt2varqi128_maskz", IX86_BUILTIN_VPERMT2VARQI128_MASKZ, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI_HI }, { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermi2varv32qi3_mask, "__builtin_ia32_vpermi2varqi256_mask", IX86_BUILTIN_VPERMI2VARQI256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI_SI }, { OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VL, CODE_FOR_avx512vl_vpermi2varv16qi3_mask, "__builtin_ia32_vpermi2varqi128_mask", IX86_BUILTIN_VPERMI2VARQI128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI_HI }, }; @@ -37717,6 +37760,7 @@ ix86_expand_args_builtin (const struct builtin_description *d, case 5: pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op, args[2].op, args[3].op, args[4].op); + break; case 6: pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op, args[2].op, args[3].op, args[4].op, @@ -38092,6 +38136,7 @@ ix86_expand_round_builtin (const struct builtin_description *d, case 5: pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op, args[3].op, args[4].op); + break; case 6: pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op, args[3].op, args[4].op, @@ -38246,7 +38291,11 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, memory = 0; break; case VOID_FTYPE_PV8DF_V8DF_QI: + case VOID_FTYPE_PV4DF_V4DF_QI: + case VOID_FTYPE_PV2DF_V2DF_QI: case VOID_FTYPE_PV16SF_V16SF_HI: + case VOID_FTYPE_PV8SF_V8SF_QI: + case VOID_FTYPE_PV4SF_V4SF_QI: case VOID_FTYPE_PV8DI_V8DI_QI: case VOID_FTYPE_PV4DI_V4DI_QI: case VOID_FTYPE_PV2DI_V2DI_QI: @@ -38306,10 +38355,6 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, case VOID_FTYPE_PV16QI_V16QI_HI: case VOID_FTYPE_PV32QI_V32QI_SI: case VOID_FTYPE_PV64QI_V64QI_DI: - case VOID_FTYPE_PV4DF_V4DF_QI: - case VOID_FTYPE_PV2DF_V2DF_QI: - case VOID_FTYPE_PV8SF_V8SF_QI: - case VOID_FTYPE_PV4SF_V4SF_QI: nargs = 2; klass = store; /* Reserve memory operand for target. */ @@ -40246,13 +40291,12 @@ rdseed_step: op0 = fixup_modeless_constant (op0, mode0); - if (GET_MODE (op0) == mode0 - || (GET_MODE (op0) == VOIDmode && op0 != constm1_rtx)) + if (GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode) { if (!insn_data[icode].operand[0].predicate (op0, mode0)) op0 = copy_to_mode_reg (mode0, op0); } - else if (op0 != constm1_rtx) + else { op0 = copy_to_reg (op0); op0 = simplify_gen_subreg (mode0, op0, GET_MODE (op0), 0); @@ -45078,6 +45122,7 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) { /* For SSE1, we have to reuse the V4SF code. */ rtx t = gen_reg_rtx (V4SFmode); + emit_move_insn (t, gen_lowpart (V4SFmode, target)); ix86_expand_vector_set (false, t, gen_lowpart (SFmode, val), elt); emit_move_insn (target, gen_lowpart (mode, t)); } @@ -45208,7 +45253,12 @@ half: 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, + /* The avx512*_blendm expanders have different operand order + from VEC_MERGE. In VEC_MERGE, the first input operand is used for + elements where the mask is set and second input operand otherwise, + in {sse,avx}*_*blend* the first input operand is used for elements + where the mask is clear and second input operand otherwise. */ + emit_insn (gen_blendm (target, target, tmp, force_reg (mmode, gen_int_mode (1 << elt, mmode)))); } @@ -50025,16 +50075,24 @@ ix86_expand_vecop_qihi (enum rtx_code code, rtx dest, rtx op1, rtx op2) { /* For SSE2, we used an full interleave, so the desired results are in the even elements. */ - for (i = 0; i < 64; ++i) + for (i = 0; i < d.nelt; ++i) d.perm[i] = i * 2; } else { /* For AVX, the interleave used above was not cross-lane. So the extraction is evens but with the second and third quarter swapped. - Happily, that is even one insn shorter than even extraction. */ - for (i = 0; i < 64; ++i) - d.perm[i] = i * 2 + ((i & 24) == 8 ? 16 : (i & 24) == 16 ? -16 : 0); + Happily, that is even one insn shorter than even extraction. + For AVX512BW we have 4 lanes. We extract evens from within a lane, + always first from the first and then from the second source operand, + the index bits above the low 4 bits remains the same. + Thus, for d.nelt == 32 we want permutation + 0,2,4,..14, 32,34,36,..46, 16,18,20,..30, 48,50,52,..62 + and for d.nelt == 64 we want permutation + 0,2,4,..14, 64,66,68,..78, 16,18,20,..30, 80,82,84,..94, + 32,34,36,..46, 96,98,100,..110, 48,50,52,..62, 112,114,116,..126. */ + for (i = 0; i < d.nelt; ++i) + d.perm[i] = ((i * 2) & 14) + ((i & 8) ? d.nelt : 0) + (i & ~15); } ok = ix86_expand_vec_perm_const_1 (&d); diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.h b/contrib/gcc-5.0/gcc/config/i386/i386.h index d5a5263108..884cda3377 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.h +++ b/contrib/gcc-5.0/gcc/config/i386/i386.h @@ -454,6 +454,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST]; ix86_tune_features[X86_TUNE_SLOW_PSHUFB] #define TARGET_VECTOR_PARALLEL_EXECUTION \ ix86_tune_features[X86_TUNE_VECTOR_PARALLEL_EXECUTION] +#define TARGET_AVOID_4BYTE_PREFIXES \ + ix86_tune_features[X86_TUNE_AVOID_4BYTE_PREFIXES] #define TARGET_FUSE_CMP_AND_BRANCH_32 \ ix86_tune_features[X86_TUNE_FUSE_CMP_AND_BRANCH_32] #define TARGET_FUSE_CMP_AND_BRANCH_64 \ diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.md b/contrib/gcc-5.0/gcc/config/i386/i386.md index 8b1d372c58..42c5da9e04 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.md +++ b/contrib/gcc-5.0/gcc/config/i386/i386.md @@ -1866,7 +1866,7 @@ [(set (match_operand:XI 0 "nonimmediate_operand") (match_operand:XI 1 "general_operand"))] "TARGET_AVX512F" - "ix86_expand_move (XImode, operands); DONE;") + "ix86_expand_vector_move (XImode, operands); DONE;") ;; Reload patterns to support multi-word load/store ;; with non-offsetable address. @@ -1906,11 +1906,11 @@ [(set (match_operand:OI 0 "nonimmediate_operand") (match_operand:OI 1 "general_operand"))] "TARGET_AVX" - "ix86_expand_move (OImode, operands); DONE;") + "ix86_expand_vector_move (OImode, operands); DONE;") (define_expand "movti" [(set (match_operand:TI 0 "nonimmediate_operand") - (match_operand:TI 1 "nonimmediate_operand"))] + (match_operand:TI 1 "general_operand"))] "TARGET_64BIT || TARGET_SSE" { if (TARGET_64BIT) @@ -2416,7 +2416,7 @@ (define_insn "kmovw" [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k") (unspec:HI - [(match_operand:HI 1 "nonimmediate_operand" "rm,k")] + [(match_operand:HI 1 "nonimmediate_operand" "r,km")] UNSPEC_KMOV))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F" "@ @@ -2428,8 +2428,8 @@ (define_insn "*movhi_internal" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm") - (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m") + (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -2443,7 +2443,8 @@ switch (which_alternative) { case 4: return "kmovw\t{%k1, %0|%0, %k1}"; - case 5: return "kmovw\t{%1, %0|%0, %1}"; + case 5: /* FALLTHRU */ + case 7: return "kmovw\t{%1, %0|%0, %1}"; case 6: return "kmovw\t{%1, %k0|%k0, %1}"; default: gcc_unreachable (); } @@ -2456,7 +2457,7 @@ } } [(set (attr "type") - (cond [(eq_attr "alternative" "4,5,6") + (cond [(eq_attr "alternative" "4,5,6,7") (const_string "mskmov") (match_test "optimize_function_for_size_p (cfun)") (const_string "imov") @@ -2473,7 +2474,7 @@ ] (const_string "imov"))) (set (attr "prefix") - (if_then_else (eq_attr "alternative" "4,5,6") + (if_then_else (eq_attr "alternative" "4,5,6,7") (const_string "vex") (const_string "orig"))) (set (attr "mode") @@ -2973,7 +2974,7 @@ (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))] "(TARGET_64BIT || TARGET_SSE) && !(MEM_P (operands[0]) && MEM_P (operands[1])) - && (!can_create_pseudo_p () + && (lra_in_progress || reload_completed || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) || GET_CODE (operands[1]) != CONST_DOUBLE || (optimize_function_for_size_p (cfun) @@ -3043,7 +3044,7 @@ (match_operand:XF 1 "general_operand" "fm,f,G,roF,r , *roF,*r,F ,C"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) - && (!can_create_pseudo_p () + && (lra_in_progress || reload_completed || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) || GET_CODE (operands[1]) != CONST_DOUBLE || (optimize_function_for_size_p (cfun) @@ -3097,7 +3098,7 @@ (match_operand:DF 1 "general_operand" "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) - && (!can_create_pseudo_p () + && (lra_in_progress || reload_completed || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) || GET_CODE (operands[1]) != CONST_DOUBLE || (optimize_function_for_size_p (cfun) @@ -3280,7 +3281,7 @@ (match_operand:SF 1 "general_operand" "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) - && (!can_create_pseudo_p () + && (lra_in_progress || reload_completed || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) || GET_CODE (operands[1]) != CONST_DOUBLE || (optimize_function_for_size_p (cfun) @@ -7998,10 +7999,10 @@ (clobber (reg:CC FLAGS_REG))] "TARGET_AVX512F && !TARGET_BMI && reload_completed" [(set (match_dup 0) - (not:HI (match_dup 0))) + (not:SWI12 (match_dup 0))) (parallel [(set (match_dup 0) - (and:HI (match_dup 0) - (match_dup 1))) + (and:SWI12 (match_dup 0) + (match_dup 1))) (clobber (reg:CC FLAGS_REG))])]) ;; Turn *anddi_1 into *andsi_1_zext if possible. @@ -11644,7 +11645,8 @@ (zero_extend (match_dup 1)))] "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) - && ! reg_overlap_mentioned_p (operands[3], operands[0])" + && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && ! reg_set_p (operands[3], operands[4])" [(parallel [(set (match_dup 5) (match_dup 0)) (match_dup 4)]) (set (strict_low_part (match_dup 6)) @@ -11687,7 +11689,8 @@ (clobber (reg:CC FLAGS_REG))])] "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) - && ! reg_overlap_mentioned_p (operands[3], operands[0])" + && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && ! reg_set_p (operands[3], operands[4])" [(parallel [(set (match_dup 5) (match_dup 0)) (match_dup 4)]) (set (strict_low_part (match_dup 6)) diff --git a/contrib/gcc-5.0/gcc/config/i386/sse.md b/contrib/gcc-5.0/gcc/config/i386/sse.md index dc7f6a7bab..df50e7d509 100644 --- a/contrib/gcc-5.0/gcc/config/i386/sse.md +++ b/contrib/gcc-5.0/gcc/config/i386/sse.md @@ -483,8 +483,9 @@ [(V16SF "f") (V16SI "i") (V8DF "f") (V8DI "i") (V8SF "f") (V8SI "i") (V4DF "f") (V4DI "i") (V4SF "f") (V4SI "i") (V2DF "f") (V2DI "i") - (V32QI "i") (V16HI "u") (V16QI "i") (V8HI "i") - (V64QI "i") (V1TI "i") (V2TI "i")]) + (V32HI "i") (V16HI "i") (V8HI "i") + (V64QI "i") (V32QI "i") (V16QI "i") + (V4TI "i") (V2TI "i") (V1TI "i")]) (define_mode_attr ssequartermode [(V16SF "V4SF") (V8DF "V2DF") (V16SI "V4SI") (V8DI "V2DI")]) @@ -677,7 +678,8 @@ ;; Pointer size override for scalar modes (Intel asm dialect) (define_mode_attr iptr - [(V32QI "b") (V16HI "w") (V8SI "k") (V4DI "q") + [(V64QI "b") (V32HI "w") (V16SI "k") (V8DI "q") + (V32QI "b") (V16HI "w") (V8SI "k") (V4DI "q") (V16QI "b") (V8HI "w") (V4SI "k") (V2DI "q") (V8SF "k") (V4DF "q") (V4SF "k") (V2DF "q") @@ -704,7 +706,8 @@ (V64QI "8") (V32QI "8") (V16QI "8") (V32HI "16") (V16HI "16") (V8HI "16") (V16SI "32") (V8SI "32") (V4SI "32") - (V16SF "32") (V8DF "64")]) + (V16SF "32") (V8SF "32") (V4SF "32") + (V8DF "64") (V4DF "64") (V2DF "64")]) ;; SSE prefix for integer vector modes (define_mode_attr sseintprefix @@ -804,7 +807,7 @@ (define_insn "*mov_internal" [(set (match_operand:VMOVE 0 "nonimmediate_operand" "=v,v ,m") - (match_operand:VMOVE 1 "nonimmediate_or_sse_const_operand" "C ,vm,v"))] + (match_operand:VMOVE 1 "nonimmediate_or_sse_const_operand" "BC,vm,v"))] "TARGET_SSE && (register_operand (operands[0], mode) || register_operand (operands[1], mode))" @@ -1022,7 +1025,7 @@ sse_suffix = ""; } - if (misaligned_operand (operands[1], mode)) + if (misaligned_operand (operands[0], mode)) align = "u"; else align = "a"; @@ -2605,7 +2608,7 @@ (match_operator: 3 "sse_comparison_operator" [(match_operand:VF 1 "register_operand" "v") (match_operand:VF 2 "nonimmediate_operand" "vm")]))] - "TARGET_SSE" + "TARGET_AVX512F" "vcmp%D3\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "ssecmp") (set_attr "length_immediate" "1") @@ -3855,7 +3858,7 @@ "@ cvtsi2ss\t{%2, %0|%0, %2} cvtsi2ss\t{%2, %0|%0, %2} - vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}" + vcvtsi2ss\t{%2, %1, %0|%0, %1, %2}" [(set_attr "isa" "noavx,noavx,avx") (set_attr "type" "sseicvt") (set_attr "athlon_decode" "vector,double,*") @@ -3876,7 +3879,7 @@ "@ cvtsi2ssq\t{%2, %0|%0, %2} cvtsi2ssq\t{%2, %0|%0, %2} - vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}" + vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}" [(set_attr "isa" "noavx,noavx,avx") (set_attr "type" "sseicvt") (set_attr "athlon_decode" "vector,double,*") @@ -3989,7 +3992,7 @@ (match_operand:VF_128 1 "register_operand" "v") (const_int 1)))] "TARGET_AVX512F && " - "vcvtusi2\t{%2, %1, %0|%0, %1, %2}" + "vcvtusi2\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseicvt") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -4003,7 +4006,7 @@ (match_operand:VF_128 1 "register_operand" "v") (const_int 1)))] "TARGET_AVX512F && TARGET_64BIT" - "vcvtusi2\t{%2, %1, %0|%0, %1, %2}" + "vcvtusi2\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseicvt") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -4268,7 +4271,7 @@ "@ cvtsi2sdq\t{%2, %0|%0, %2} cvtsi2sdq\t{%2, %0|%0, %2} - vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}" + vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}" [(set_attr "isa" "noavx,noavx,avx") (set_attr "type" "sseicvt") (set_attr "athlon_decode" "double,direct,*") @@ -7018,28 +7021,50 @@ DONE; }) -(define_insn "vec_extract_hi_" - [(set (match_operand: 0 "" "=v,") +(define_insn "vec_extract_hi__maskm" + [(set (match_operand: 0 "memory_operand" "=m") + (vec_merge: + (vec_select: + (match_operand:VI8F_256 1 "register_operand" "v") + (parallel [(const_int 2) (const_int 3)])) + (match_operand: 2 "memory_operand" "0") + (match_operand: 3 "register_operand" "k")))] + "TARGET_AVX512DQ && TARGET_AVX512VL + && rtx_equal_p (operands[2], operands[0])" + "vextract64x2\t{$0x1, %1, %0%{%3%}|%0%{%3%}, %1, 0x1}" + [(set_attr "type" "sselog1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "evex") + (set_attr "mode" "")]) + +(define_insn "vec_extract_hi__mask" + [(set (match_operand: 0 "register_operand" "=v") + (vec_merge: + (vec_select: + (match_operand:VI8F_256 1 "register_operand" "v") + (parallel [(const_int 2) (const_int 3)])) + (match_operand: 2 "vector_move_operand" "0C") + (match_operand: 3 "register_operand" "Yk")))] + "TARGET_AVX512VL && TARGET_AVX512DQ" + "vextract64x2\t{$0x1, %1, %0%{%3%}%N2|%0%{%3%}%N2, %1, 0x1}" + [(set_attr "type" "sselog1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "evex") + (set_attr "mode" "")]) + +(define_insn "vec_extract_hi_" + [(set (match_operand: 0 "nonimmediate_operand" "=xm, vm") (vec_select: - (match_operand:VI8F_256 1 "register_operand" "v,v") + (match_operand:VI8F_256 1 "register_operand" "x, v") (parallel [(const_int 2) (const_int 3)])))] - "TARGET_AVX && && " -{ - if (TARGET_AVX512VL) - { - if (TARGET_AVX512DQ) - return "vextract64x2\t{$0x1, %1, %0|%0, %1, 0x1}"; - else - return "vextract32x4\t{$0x1, %1, %0|%0, %1, 0x1}"; - } - else - return "vextract\t{$0x1, %1, %0|%0, %1, 0x1}"; -} - [(set_attr "type" "sselog") - (set_attr "prefix_extra" "1") + "TARGET_AVX" + "@ + vextract\t{$0x1, %1, %0|%0, %1, 0x1} + vextract64x2\t{$0x1, %1, %0|%0, %1, 0x1}" + [(set_attr "isa" "*, avx512dq") + (set_attr "prefix" "vex, evex") + (set_attr "type" "sselog1") (set_attr "length_immediate" "1") - (set_attr "memory" "none,store") - (set_attr "prefix" "vex") (set_attr "mode" "")]) (define_split @@ -10802,45 +10827,46 @@ case MODE_XI: gcc_assert (TARGET_AVX512F); case MODE_OI: - gcc_assert (TARGET_AVX2 || TARGET_AVX512VL); + gcc_assert (TARGET_AVX2); case MODE_TI: - gcc_assert (TARGET_SSE2 || TARGET_AVX512VL); + gcc_assert (TARGET_SSE2); switch (mode) - { - case V16SImode: - case V8DImode: - if (TARGET_AVX512F) - { - tmp = "pandn"; - break; - } - case V8SImode: - case V4DImode: - case V4SImode: - case V2DImode: - if (TARGET_AVX512VL) - { - tmp = "pandn"; - break; - } - default: - tmp = TARGET_AVX512VL ? "pandnq" : "pandn"; - } + { + case V64QImode: + case V32HImode: + /* There is no vpandnb or vpandnw instruction, nor vpandn for + 512-bit vectors. Use vpandnq instead. */ + tmp = "pandnq"; + break; + case V16SImode: + case V8DImode: + tmp = "pandn"; + break; + case V8SImode: + case V4DImode: + case V4SImode: + case V2DImode: + tmp = TARGET_AVX512VL ? "pandn" : "pandn"; + break; + default: + tmp = TARGET_AVX512VL ? "pandnq" : "pandn"; + break; + } break; - case MODE_V16SF: + case MODE_V16SF: gcc_assert (TARGET_AVX512F); - case MODE_V8SF: + case MODE_V8SF: gcc_assert (TARGET_AVX); - case MODE_V4SF: + case MODE_V4SF: gcc_assert (TARGET_SSE); tmp = "andnps"; break; - default: + default: gcc_unreachable (); - } + } switch (which_alternative) { @@ -10848,7 +10874,7 @@ ops = "%s\t{%%2, %%0|%%0, %%2}"; break; case 1: - ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; + ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}"; break; default: gcc_unreachable (); @@ -10898,21 +10924,6 @@ (set_attr "prefix" "evex") (set_attr "mode" "")]) -(define_insn "*andnot3_mask" - [(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v") - (vec_merge:VI12_AVX512VL - (and:VI12_AVX512VL - (not:VI12_AVX512VL - (match_operand:VI12_AVX512VL 1 "register_operand" "v")) - (match_operand:VI12_AVX512VL 2 "nonimmediate_operand" "vm")) - (match_operand:VI12_AVX512VL 3 "vector_move_operand" "0C") - (match_operand: 4 "register_operand" "Yk")))] - "TARGET_AVX512BW" - "vpandn\t{%2, %1, %0%{%4%}%N3|%0%{%4%}%N3, %1, %2}"; - [(set_attr "type" "sselog") - (set_attr "prefix" "evex") - (set_attr "mode" "")]) - (define_expand "3" [(set (match_operand:VI 0 "register_operand") (any_logic:VI @@ -11834,13 +11845,13 @@ { int mask = INTVAL (operands[3]); if (mask == 0) - emit_insn (gen_vec_set_lo__mask - (operands[0], operands[1], operands[2], - operands[4], operands[5])); + emit_insn (gen_vec_set_lo__mask (operands[0], operands[1], + operands[2], operands[4], + operands[5])); else - emit_insn (gen_vec_set_hi__mask - (operands[0], operands[1], operands[2], - operands[4], operands[5])); + emit_insn (gen_vec_set_hi__mask (operands[0], operands[1], + operands[2], operands[4], + operands[5])); DONE; }) @@ -11851,9 +11862,9 @@ (vec_select: (match_operand:V16FI 1 "register_operand" "v") (parallel [(const_int 8) (const_int 9) - (const_int 10) (const_int 11) - (const_int 12) (const_int 13) - (const_int 14) (const_int 15)]))))] + (const_int 10) (const_int 11) + (const_int 12) (const_int 13) + (const_int 14) (const_int 15)]))))] "TARGET_AVX512DQ" "vinsert32x8\t{$0x0, %2, %1, %0|%0, %1, %2, $0x0}" [(set_attr "type" "sselog") @@ -11864,13 +11875,13 @@ (define_insn "vec_set_hi_" [(set (match_operand:V16FI 0 "register_operand" "=v") (vec_concat:V16FI - (match_operand: 2 "nonimmediate_operand" "vm") (vec_select: (match_operand:V16FI 1 "register_operand" "v") (parallel [(const_int 0) (const_int 1) - (const_int 2) (const_int 3) - (const_int 4) (const_int 5) - (const_int 6) (const_int 7)]))))] + (const_int 2) (const_int 3) + (const_int 4) (const_int 5) + (const_int 6) (const_int 7)])) + (match_operand: 2 "nonimmediate_operand" "vm")))] "TARGET_AVX512DQ" "vinsert32x8\t{$0x1, %2, %1, %0|%0, %1, %2, $0x1}" [(set_attr "type" "sselog") @@ -11885,7 +11896,7 @@ (vec_select: (match_operand:V8FI 1 "register_operand" "v") (parallel [(const_int 4) (const_int 5) - (const_int 6) (const_int 7)]))))] + (const_int 6) (const_int 7)]))))] "TARGET_AVX512F" "vinsert64x4\t{$0x0, %2, %1, %0|%0, %1, %2, $0x0}" [(set_attr "type" "sselog") @@ -11896,11 +11907,11 @@ (define_insn "vec_set_hi_" [(set (match_operand:V8FI 0 "register_operand" "=v") (vec_concat:V8FI - (match_operand: 2 "nonimmediate_operand" "vm") (vec_select: (match_operand:V8FI 1 "register_operand" "v") (parallel [(const_int 0) (const_int 1) - (const_int 2) (const_int 3)]))))] + (const_int 2) (const_int 3)])) + (match_operand: 2 "nonimmediate_operand" "vm")))] "TARGET_AVX512F" "vinsert64x4\t{$0x1, %2, %1, %0|%0, %1, %2, $0x1}" [(set_attr "type" "sselog") @@ -15188,7 +15199,7 @@ (define_expand "avx512pf_gatherpfsf" [(unspec - [(match_operand: 0 "register_or_constm1_operand") + [(match_operand: 0 "register_operand") (mem: (match_par_dup 5 [(match_operand 2 "vsib_address_operand") @@ -15230,37 +15241,10 @@ (set_attr "prefix" "evex") (set_attr "mode" "XI")]) -(define_insn "*avx512pf_gatherpfsf" - [(unspec - [(const_int -1) - (match_operator: 4 "vsib_mem_operator" - [(unspec:P - [(match_operand:P 1 "vsib_address_operand" "Tv") - (match_operand:VI48_512 0 "register_operand" "v") - (match_operand:SI 2 "const1248_operand" "n")] - UNSPEC_VSIBADDR)]) - (match_operand:SI 3 "const_2_to_3_operand" "n")] - UNSPEC_GATHER_PREFETCH)] - "TARGET_AVX512PF" -{ - switch (INTVAL (operands[3])) - { - case 3: - return "vgatherpf0ps\t{%4|%4}"; - case 2: - return "vgatherpf1ps\t{%4|%4}"; - default: - gcc_unreachable (); - } -} - [(set_attr "type" "sse") - (set_attr "prefix" "evex") - (set_attr "mode" "XI")]) - ;; Packed double variants (define_expand "avx512pf_gatherpfdf" [(unspec - [(match_operand: 0 "register_or_constm1_operand") + [(match_operand: 0 "register_operand") (mem:V8DF (match_par_dup 5 [(match_operand 2 "vsib_address_operand") @@ -15302,37 +15286,10 @@ (set_attr "prefix" "evex") (set_attr "mode" "XI")]) -(define_insn "*avx512pf_gatherpfdf" - [(unspec - [(const_int -1) - (match_operator:V8DF 4 "vsib_mem_operator" - [(unspec:P - [(match_operand:P 1 "vsib_address_operand" "Tv") - (match_operand:VI4_256_8_512 0 "register_operand" "v") - (match_operand:SI 2 "const1248_operand" "n")] - UNSPEC_VSIBADDR)]) - (match_operand:SI 3 "const_2_to_3_operand" "n")] - UNSPEC_GATHER_PREFETCH)] - "TARGET_AVX512PF" -{ - switch (INTVAL (operands[3])) - { - case 3: - return "vgatherpf0pd\t{%4|%4}"; - case 2: - return "vgatherpf1pd\t{%4|%4}"; - default: - gcc_unreachable (); - } -} - [(set_attr "type" "sse") - (set_attr "prefix" "evex") - (set_attr "mode" "XI")]) - ;; Packed float variants (define_expand "avx512pf_scatterpfsf" [(unspec - [(match_operand: 0 "register_or_constm1_operand") + [(match_operand: 0 "register_operand") (mem: (match_par_dup 5 [(match_operand 2 "vsib_address_operand") @@ -15376,39 +15333,10 @@ (set_attr "prefix" "evex") (set_attr "mode" "XI")]) -(define_insn "*avx512pf_scatterpfsf" - [(unspec - [(const_int -1) - (match_operator: 4 "vsib_mem_operator" - [(unspec:P - [(match_operand:P 1 "vsib_address_operand" "Tv") - (match_operand:VI48_512 0 "register_operand" "v") - (match_operand:SI 2 "const1248_operand" "n")] - UNSPEC_VSIBADDR)]) - (match_operand:SI 3 "const2367_operand" "n")] - UNSPEC_SCATTER_PREFETCH)] - "TARGET_AVX512PF" -{ - switch (INTVAL (operands[3])) - { - case 3: - case 7: - return "vscatterpf0ps\t{%4|%4}"; - case 2: - case 6: - return "vscatterpf1ps\t{%4|%4}"; - default: - gcc_unreachable (); - } -} - [(set_attr "type" "sse") - (set_attr "prefix" "evex") - (set_attr "mode" "XI")]) - ;; Packed double variants (define_expand "avx512pf_scatterpfdf" [(unspec - [(match_operand: 0 "register_or_constm1_operand") + [(match_operand: 0 "register_operand") (mem:V8DF (match_par_dup 5 [(match_operand 2 "vsib_address_operand") @@ -15452,35 +15380,6 @@ (set_attr "prefix" "evex") (set_attr "mode" "XI")]) -(define_insn "*avx512pf_scatterpfdf" - [(unspec - [(const_int -1) - (match_operator:V8DF 4 "vsib_mem_operator" - [(unspec:P - [(match_operand:P 1 "vsib_address_operand" "Tv") - (match_operand:VI4_256_8_512 0 "register_operand" "v") - (match_operand:SI 2 "const1248_operand" "n")] - UNSPEC_VSIBADDR)]) - (match_operand:SI 3 "const2367_operand" "n")] - UNSPEC_SCATTER_PREFETCH)] - "TARGET_AVX512PF" -{ - switch (INTVAL (operands[3])) - { - case 3: - case 7: - return "vscatterpf0pd\t{%4|%4}"; - case 2: - case 6: - return "vscatterpf1pd\t{%4|%4}"; - default: - gcc_unreachable (); - } -} - [(set_attr "type" "sse") - (set_attr "prefix" "evex") - (set_attr "mode" "XI")]) - (define_insn "avx512er_exp2" [(set (match_operand:VF_512 0 "register_operand" "=v") (unspec:VF_512 @@ -16745,8 +16644,9 @@ (match_operand:VI_AVX512BW 1 "nonimmediate_operand" "v,m") (parallel [(const_int 0)]))))] "TARGET_AVX512F" - "vpbroadcast\t{%1, %0|%0, %1} - vpbroadcast\t{%x1, %0|%0, %x1}" + "@ + vpbroadcast\t{%x1, %0|%0, %x1} + vpbroadcast\t{%x1, %0|%0, %1}" [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -16758,7 +16658,17 @@ (match_operand: 1 "nonimmediate_operand" "vm") (parallel [(const_int 0)]))))] "TARGET_AVX512F" - "vbroadcast\t{%1, %0|%0, %1}" +{ + /* There is no DF broadcast (in AVX-512*) to 128b register. + Mimic it with integer variant. */ + if (mode == V2DFmode) + return "vpbroadcastq\t{%1, %0|%0, %q1}"; + + if (GET_MODE_SIZE (GET_MODE_INNER (mode)) == 4) + return "vbroadcast\t{%1, %0|%0, %k1}"; + else + return "vbroadcast\t{%1, %0|%0, %q1}"; +} [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -16901,26 +16811,28 @@ vbroadcast\t{%1, %0|%0, %1} vbroadcast\t{%x1, %0|%0, %x1} #" - [(set_attr "type" "ssemov") + [(set_attr "isa" "*,*,noavx512vl") + (set_attr "type" "ssemov") (set_attr "prefix_extra" "1") (set_attr "prefix" "maybe_evex") (set_attr "mode" "")]) (define_insn "vec_dup" - [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,x,v,x") + [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,x,x,v,x") (vec_duplicate:AVX_VEC_DUP_MODE - (match_operand: 1 "nonimmediate_operand" "m,m,v,?x")))] + (match_operand: 1 "nonimmediate_operand" "m,m,x,v,?x")))] "TARGET_AVX" "@ vbroadcast\t{%1, %0|%0, %1} vbroadcast\t{%1, %0|%0, %1} vbroadcast\t{%x1, %0|%0, %x1} + vbroadcast\t{%x1, %g0|%g0, %x1} #" [(set_attr "type" "ssemov") (set_attr "prefix_extra" "1") (set_attr "prefix" "maybe_evex") - (set_attr "isa" "avx2,noavx2,avx2,noavx2") - (set_attr "mode" ",V8SF,,V8SF")]) + (set_attr "isa" "avx2,noavx2,avx2,avx512f,noavx2") + (set_attr "mode" ",V8SF,,,V8SF")]) (define_split [(set (match_operand:AVX2_VEC_DUP_MODE 0 "register_operand") @@ -18524,7 +18436,7 @@ (match_operand:SI 3 "const_0_to_15_operand")] UNSPEC_RANGE))] "TARGET_AVX512DQ && " - "vrange\t{%3, %2, %1, %0|%0, %1, %2, %3}" + "vrange\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -18540,7 +18452,7 @@ (match_dup 1) (const_int 1)))] "TARGET_AVX512DQ" - "vrange\t{%3, %2, %1, %0|%0, %1, %2, %3}" + "vrange\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse") (set_attr "prefix" "evex") (set_attr "mode" "")]) diff --git a/contrib/gcc-5.0/gcc/cp/call.c b/contrib/gcc-5.0/gcc/cp/call.c index 0df408c917..e9d9dedf0f 100644 --- a/contrib/gcc-5.0/gcc/cp/call.c +++ b/contrib/gcc-5.0/gcc/cp/call.c @@ -213,7 +213,6 @@ static struct z_candidate *add_function_candidate tree, int, tsubst_flags_t); static conversion *implicit_conversion (tree, tree, tree, bool, int, tsubst_flags_t); -static conversion *standard_conversion (tree, tree, tree, bool, int); static conversion *reference_binding (tree, tree, tree, bool, int, tsubst_flags_t); static conversion *build_conv (conversion_kind, tree, conversion *); @@ -924,6 +923,8 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) if (i < CONSTRUCTOR_NELTS (ctor)) val = CONSTRUCTOR_ELT (ctor, i)->value; + else if (DECL_INITIAL (field)) + val = get_nsdmi (field, /*ctor*/false); else if (TREE_CODE (ftype) == REFERENCE_TYPE) /* Value-initialization of reference is ill-formed. */ return NULL; @@ -1106,7 +1107,7 @@ strip_top_quals (tree t) static conversion * standard_conversion (tree to, tree from, tree expr, bool c_cast_p, - int flags) + int flags, tsubst_flags_t complain) { enum tree_code fcode, tcode; conversion *conv; @@ -1136,7 +1137,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, else if (TREE_CODE (to) == BOOLEAN_TYPE) { /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961). */ - expr = resolve_nondeduced_context (expr); + expr = resolve_nondeduced_context (expr, complain); from = TREE_TYPE (expr); } } @@ -1175,7 +1176,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, the standard conversion sequence to perform componentwise conversion. */ conversion *part_conv = standard_conversion - (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags); + (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags, + complain); if (part_conv) { @@ -1814,7 +1816,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, c_cast_p, flags, complain); else - conv = standard_conversion (to, from, expr, c_cast_p, flags); + conv = standard_conversion (to, from, expr, c_cast_p, flags, complain); if (conv) return conv; @@ -1920,7 +1922,7 @@ add_candidate (struct z_candidate **candidates, /* Return the number of remaining arguments in the parameter list beginning with ARG. */ -static int +int remaining_arguments (tree arg) { int n; @@ -5980,7 +5982,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, argarray[0] = addr; for (i = 1; i < nargs; i++) argarray[i] = CALL_EXPR_ARG (placement, i); - mark_used (fn); + if (!mark_used (fn, complain) && !(complain & tf_error)) + return error_mark_node; return build_cxx_call (fn, nargs, argarray, complain); } else @@ -6247,8 +6250,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* When converting from an init list we consider explicit constructors, but actually trying to call one is an error. */ if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn) + && BRACE_ENCLOSED_INITIALIZER_P (expr) /* Unless this is for direct-list-initialization. */ - && !DIRECT_LIST_INIT_P (expr)) + && !CONSTRUCTOR_IS_DIRECT_INIT (expr)) { if (!(complain & tf_error)) return error_mark_node; @@ -7025,12 +7029,16 @@ static bool unsafe_copy_elision_p (tree target, tree exp) { tree type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - if (type == CLASSTYPE_AS_BASE (type)) + /* It's safe to elide the copy for a class with no tail padding. */ + if (tree_int_cst_equal (TYPE_SIZE (type), CLASSTYPE_SIZE (type))) return false; - if (!is_base_field_ref (target) - && resolves_to_fixed_type_p (target, NULL)) + /* It's safe to elide the copy if we aren't initializing a base object. */ + if (!is_base_field_ref (target)) return false; tree init = TARGET_EXPR_INITIAL (exp); + /* build_compound_expr pushes COMPOUND_EXPR inside TARGET_EXPR. */ + while (TREE_CODE (init) == COMPOUND_EXPR) + init = TREE_OPERAND (init, 1); return (TREE_CODE (init) == AGGR_INIT_EXPR && !AGGR_INIT_VIA_CTOR_P (init)); } @@ -7435,7 +7443,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) the implementation elided its use. */ if (!trivial || DECL_DELETED_FN (fn)) { - mark_used (fn); + if (!mark_used (fn, complain) && !(complain & tf_error)) + return error_mark_node; already_used = true; } diff --git a/contrib/gcc-5.0/gcc/cp/cfns.gperf b/contrib/gcc-5.0/gcc/cp/cfns.gperf index 68acd3df48..214ecf64f5 100644 --- a/contrib/gcc-5.0/gcc/cp/cfns.gperf +++ b/contrib/gcc-5.0/gcc/cp/cfns.gperf @@ -1,3 +1,5 @@ +%language=C++ +%define class-name libc_name %{ /* Copyright (C) 2000-2015 Free Software Foundation, Inc. @@ -16,14 +18,6 @@ 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 . */ -#ifdef __GNUC__ -__inline -#endif -static unsigned int hash (const char *, unsigned int); -#ifdef __GNUC__ -__inline -#endif -const char * libc_name_p (const char *, unsigned int); %} %% # The standard C library functions, for feeding to gperf; the result is used diff --git a/contrib/gcc-5.0/gcc/cp/cfns.h b/contrib/gcc-5.0/gcc/cp/cfns.h index 1c6665d4f5..596f41335f 100644 --- a/contrib/gcc-5.0/gcc/cp/cfns.h +++ b/contrib/gcc-5.0/gcc/cp/cfns.h @@ -1,5 +1,5 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ -/* Command-line: gperf -o -C -E -k '1-6,$' -j1 -D -N libc_name_p -L ANSI-C cfns.gperf */ +/* C++ code produced by gperf version 3.0.4 */ +/* Command-line: gperf -o -C -E -k '1-6,$' -j1 -D -N libc_name_p -L C++ --output-file cfns.h cfns.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -28,7 +28,7 @@ #error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif -#line 1 "cfns.gperf" +#line 3 "cfns.gperf" /* Copyright (C) 2000-2015 Free Software Foundation, Inc. @@ -47,25 +47,18 @@ 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 . */ -#ifdef __GNUC__ -__inline -#endif -static unsigned int hash (const char *, unsigned int); -#ifdef __GNUC__ -__inline -#endif -const char * libc_name_p (const char *, unsigned int); /* maximum key range = 391, duplicates = 0 */ -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -hash (register const char *str, register unsigned int len) +class libc_name +{ +private: + static inline unsigned int hash (const char *str, unsigned int len); +public: + static const char *libc_name_p (const char *str, unsigned int len); +}; + +inline unsigned int +libc_name::hash (register const char *str, register unsigned int len) { static const unsigned short asso_values[] = { @@ -122,14 +115,8 @@ hash (register const char *str, register unsigned int len) return hval + asso_values[(unsigned char)str[len - 1]]; } -#ifdef __GNUC__ -__inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif const char * -libc_name_p (register const char *str, register unsigned int len) +libc_name::libc_name_p (register const char *str, register unsigned int len) { enum { diff --git a/contrib/gcc-5.0/gcc/cp/class.c b/contrib/gcc-5.0/gcc/cp/class.c index f3ec826c86..9dc15da282 100644 --- a/contrib/gcc-5.0/gcc/cp/class.c +++ b/contrib/gcc-5.0/gcc/cp/class.c @@ -7784,8 +7784,8 @@ resolve_address_of_overloaded_function (tree target_type, /* Make =delete work with SFINAE. */ if (DECL_DELETED_FN (fn) && !(flags & tf_error)) return error_mark_node; - - mark_used (fn); + if (!mark_used (fn, flags) && !(flags & tf_error)) + return error_mark_node; } /* We could not check access to member functions when this diff --git a/contrib/gcc-5.0/gcc/cp/constexpr.c b/contrib/gcc-5.0/gcc/cp/constexpr.c index ba9fd0e046..50e2338a13 100644 --- a/contrib/gcc-5.0/gcc/cp/constexpr.c +++ b/contrib/gcc-5.0/gcc/cp/constexpr.c @@ -539,6 +539,7 @@ build_constexpr_constructor_member_initializers (tree type, tree body) { vec *vec = NULL; bool ok = true; + top: if (TREE_CODE (body) == MUST_NOT_THROW_EXPR || TREE_CODE (body) == EH_SPEC_BLOCK) body = TREE_OPERAND (body, 0); @@ -550,6 +551,8 @@ build_constexpr_constructor_member_initializers (tree type, tree body) body = tsi_stmt (i); if (TREE_CODE (body) == BIND_EXPR) break; + if (TREE_CODE (body) == MUST_NOT_THROW_EXPR) + goto top; } } if (TREE_CODE (body) == BIND_EXPR) @@ -896,6 +899,9 @@ struct constexpr_ctx { /* Values for any temporaries or local variables within the constant-expression. */ hash_map *values; + /* SAVE_EXPRs that we've seen within the current LOOP_EXPR. NULL if we + aren't inside a loop. */ + hash_set *save_exprs; /* The CONSTRUCTOR we're currently building up for an aggregate initializer. */ tree ctor; @@ -1239,21 +1245,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, return t; } - /* Shortcut trivial constructor/op=. */ - if (trivial_fn_p (fun)) - { - if (call_expr_nargs (t) == 2) - { - tree arg = convert_from_reference (get_nth_callarg (t, 1)); - return cxx_eval_constant_expression (ctx, arg, - lval, non_constant_p, - overflow_p); - } - else if (TREE_CODE (t) == AGGR_INIT_EXPR - && AGGR_INIT_ZERO_FIRST (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)) @@ -1394,6 +1385,8 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, tree oparm = TREE_PURPOSE (bound); tree arg = TREE_VALUE (bound); gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm)); + /* Don't share a CONSTRUCTOR that might be changed. */ + arg = unshare_expr (arg); ctx->values->put (remapped, arg); bound = TREE_CHAIN (bound); remapped = DECL_CHAIN (remapped); @@ -1653,15 +1646,14 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, tree lhs, rhs; lhs = cxx_eval_constant_expression (ctx, orig_lhs, /*lval*/false, non_constant_p, overflow_p); - /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to - a local array in a constexpr function. */ - bool ptr = POINTER_TYPE_P (TREE_TYPE (lhs)); - if (!ptr) - VERIFY_CONSTANT (lhs); + /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer + subtraction. */ + if (*non_constant_p) + return t; rhs = cxx_eval_constant_expression (ctx, orig_rhs, /*lval*/false, non_constant_p, overflow_p); - if (!ptr) - VERIFY_CONSTANT (rhs); + if (*non_constant_p) + return t; location_t loc = EXPR_LOCATION (t); enum tree_code code = TREE_CODE (t); @@ -1676,6 +1668,9 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, } else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs)) *non_constant_p = true; + /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to + a local array in a constexpr function. */ + bool ptr = POINTER_TYPE_P (TREE_TYPE (lhs)); if (!ptr) VERIFY_CONSTANT (r); return r; @@ -1707,6 +1702,133 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, jump_target); } +/* Returns less than, equal to, or greater than zero if KEY is found to be + less than, to match, or to be greater than the constructor_elt's INDEX. */ + +static int +array_index_cmp (tree key, tree index) +{ + gcc_assert (TREE_CODE (key) == INTEGER_CST); + + switch (TREE_CODE (index)) + { + case INTEGER_CST: + return tree_int_cst_compare (key, index); + case RANGE_EXPR: + { + tree lo = TREE_OPERAND (index, 0); + tree hi = TREE_OPERAND (index, 1); + if (tree_int_cst_lt (key, lo)) + return -1; + else if (tree_int_cst_lt (hi, key)) + return 1; + else + return 0; + } + default: + gcc_unreachable (); + } +} + +/* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1 + if none. If INSERT is true, insert a matching element rather than fail. */ + +static HOST_WIDE_INT +find_array_ctor_elt (tree ary, tree dindex, bool insert = false) +{ + if (tree_int_cst_sgn (dindex) < 0) + return -1; + + unsigned HOST_WIDE_INT i = tree_to_uhwi (dindex); + vec *elts = CONSTRUCTOR_ELTS (ary); + unsigned HOST_WIDE_INT len = vec_safe_length (elts); + + unsigned HOST_WIDE_INT end = len; + unsigned HOST_WIDE_INT begin = 0; + + /* If the last element of the CONSTRUCTOR has its own index, we can assume + that the same is true of the other elements and index directly. */ + if (end > 0) + { + tree cindex = (*elts)[end-1].index; + if (TREE_CODE (cindex) == INTEGER_CST + && compare_tree_int (cindex, end-1) == 0) + { + if (i < end) + return i; + else + begin = end; + } + } + + /* Otherwise, find a matching index by means of a binary search. */ + while (begin != end) + { + unsigned HOST_WIDE_INT middle = (begin + end) / 2; + constructor_elt &elt = (*elts)[middle]; + tree idx = elt.index; + + int cmp = array_index_cmp (dindex, idx); + if (cmp < 0) + end = middle; + else if (cmp > 0) + begin = middle + 1; + else + { + if (insert && TREE_CODE (idx) == RANGE_EXPR) + { + /* We need to split the range. */ + constructor_elt e; + tree lo = TREE_OPERAND (idx, 0); + tree hi = TREE_OPERAND (idx, 1); + if (tree_int_cst_lt (lo, dindex)) + { + /* There are still some lower elts; shorten the range. */ + tree new_hi = int_const_binop (MINUS_EXPR, dindex, + size_one_node); + if (tree_int_cst_equal (lo, new_hi)) + /* Only one element left, no longer a range. */ + elt.index = lo; + else + TREE_OPERAND (idx, 1) = new_hi; + /* Append the element we want to insert. */ + ++middle; + e.index = dindex; + e.value = unshare_expr (elt.value); + vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e); + } + else + /* No lower elts, the range elt is now ours. */ + elt.index = dindex; + + if (tree_int_cst_lt (dindex, hi)) + { + /* There are still some higher elts; append a range. */ + tree new_lo = int_const_binop (PLUS_EXPR, dindex, + size_one_node); + if (tree_int_cst_equal (new_lo, hi)) + e.index = hi; + else + e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi); + e.value = unshare_expr (elt.value); + vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle+1, e); + } + } + return middle; + } + } + + if (insert) + { + constructor_elt e = { dindex, NULL_TREE }; + vec_safe_insert (CONSTRUCTOR_ELTS (ary), end, e); + return end; + } + + return -1; +} + + /* Subroutine of cxx_eval_constant_expression. Attempt to reduce a reference to an array slot. */ @@ -1751,37 +1873,27 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, gcc_unreachable (); } - i = tree_fits_shwi_p (index) ? tree_to_shwi (index) : -1; - bool found = true; - if (TREE_CODE (ary) == CONSTRUCTOR && len - && (TREE_CODE (CONSTRUCTOR_ELT (ary, len-1)->index) == RANGE_EXPR - || compare_tree_int (CONSTRUCTOR_ELT (ary, len-1)->index, len-1))) + if (!tree_fits_shwi_p (index) + || (i = tree_to_shwi (index)) < 0) { - /* The last element doesn't match its position in the array; this must be - a sparse array from cxx_eval_store_expression. So iterate. */ - found = false; - vec *v = CONSTRUCTOR_ELTS (ary); - constructor_elt *e; - for (unsigned ix = 0; vec_safe_iterate (v, ix, &e); ++ix) - { - if (TREE_CODE (e->index) == RANGE_EXPR) - { - tree lo = TREE_OPERAND (e->index, 0); - tree hi = TREE_OPERAND (e->index, 1); - if (tree_int_cst_le (lo, index) && tree_int_cst_le (index, hi)) - found = true; - } - else if (tree_int_cst_equal (e->index, index)) - found = true; - if (found) - { - i = ix; - break; - } - } + if (!ctx->quiet) + error ("negative array subscript"); + *non_constant_p = true; + return t; + } + + bool found; + if (TREE_CODE (ary) == CONSTRUCTOR) + { + HOST_WIDE_INT ix = find_array_ctor_elt (ary, index); + found = (ix >= 0); + if (found) + i = ix; } + else + found = (i < len); - if (i >= len || !found) + if (!found) { if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary)))) { @@ -1798,13 +1910,6 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, *non_constant_p = true; return t; } - else if (i < 0) - { - if (!ctx->quiet) - error ("negative array subscript"); - *non_constant_p = true; - return t; - } if (TREE_CODE (ary) == CONSTRUCTOR) return (*CONSTRUCTOR_ELTS (ary))[i].value; @@ -1880,11 +1985,16 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, return t; } + /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty + classes never get represented; throw together a value now. */ + if (is_really_empty_class (TREE_TYPE (t))) + return build_constructor (TREE_TYPE (t), NULL); + if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole)) { /* 'whole' is part of the aggregate initializer we're currently building; if there's no initializer for this member yet, that's an - error. */ + error. */ if (!ctx->quiet) error ("accessing uninitialized member %qD", part); *non_constant_p = true; @@ -2110,7 +2220,8 @@ verify_ctor_sanity (const constexpr_ctx *ctx, tree type) gcc_assert (ctx->ctor); gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (ctx->ctor))); - gcc_assert (CONSTRUCTOR_NELTS (ctx->ctor) == 0); + /* We used to check that ctx->ctor was empty, but that isn't the case when + the object is zero-initialized before calling the constructor. */ if (ctx->object) gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (ctx->object))); @@ -2138,6 +2249,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, unsigned i; tree index, value; FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value) { + tree orig_value = value; constexpr_ctx new_ctx; init_subob_ctx (ctx, new_ctx, index, value); if (new_ctx.ctor != ctx->ctor) @@ -2150,7 +2262,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, /* Don't VERIFY_CONSTANT here. */ if (ctx->quiet && *non_constant_p) break; - if (elt != value) + if (elt != orig_value) changed = true; if (index && TREE_CODE (index) == COMPONENT_REF) { @@ -2727,21 +2839,56 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = true; } - constructor_elt ce; + enum tree_code code = TREE_CODE (type); type = refs->pop(); - ce.index = refs->pop(); - ce.value = NULL_TREE; + tree index = refs->pop(); - unsigned HOST_WIDE_INT idx = 0; constructor_elt *cep = NULL; - for (idx = 0; - vec_safe_iterate (CONSTRUCTOR_ELTS (*valp), idx, &cep); - idx++) - /* ??? slow */ - if (cp_tree_equal (ce.index, cep->index)) - break; - if (!cep) - cep = vec_safe_push (CONSTRUCTOR_ELTS (*valp), ce); + if (code == ARRAY_TYPE) + { + HOST_WIDE_INT i + = find_array_ctor_elt (*valp, index, /*insert*/true); + gcc_assert (i >= 0); + cep = CONSTRUCTOR_ELT (*valp, i); + gcc_assert (TREE_CODE (cep->index) != RANGE_EXPR); + } + else + { + gcc_assert (TREE_CODE (index) == FIELD_DECL); + + /* We must keep the CONSTRUCTOR's ELTS in FIELD order. + Usually we meet initializers in that order, but it is + possible for base types to be placed not in program + order. */ + tree fields = TYPE_FIELDS (DECL_CONTEXT (index)); + unsigned HOST_WIDE_INT idx; + + for (idx = 0; + vec_safe_iterate (CONSTRUCTOR_ELTS (*valp), idx, &cep); + idx++) + { + if (index == cep->index) + goto found; + + /* The field we're initializing must be on the field + list. Look to see if it is present before the + field the current ELT initializes. */ + for (; fields != cep->index; fields = DECL_CHAIN (fields)) + if (index == fields) + goto insert; + } + + /* We fell off the end of the CONSTRUCTOR, so insert a new + entry at the end. */ + insert: + { + constructor_elt ce = { index, NULL_TREE }; + + vec_safe_insert (CONSTRUCTOR_ELTS (*valp), idx, ce); + cep = CONSTRUCTOR_ELT (*valp, idx); + } + found:; + } valp = &cep->value; } release_tree_vector (refs); @@ -2762,16 +2909,19 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, init = cxx_eval_constant_expression (&new_ctx, init, false, non_constant_p, overflow_p); + /* Don't share a CONSTRUCTOR that might be changed later. */ + init = unshare_expr (init); if (target == object) + /* The hash table might have moved since the get earlier. */ + valp = ctx->values->get (object); + + if (TREE_CODE (init) == CONSTRUCTOR) { - /* 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; + /* An outer ctx->ctor might be pointing to *valp, so just replace + its contents. */ + CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init); + CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) + = CONSTRUCTOR_NO_IMPLICIT_ZERO (init); } else *valp = init; @@ -2961,6 +3111,15 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t, return r; } +namespace { +bool +save_exprs_remover (const tree &expr, constexpr_ctx &ctx) +{ + ctx.values->remove (expr); + return true; +} +} + /* Evaluate a LOOP_EXPR for side-effects. Handles break and return semantics; continue semantics are covered by cxx_eval_statement_list. */ @@ -2969,16 +3128,25 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p, bool *overflow_p, tree *jump_target) { + constexpr_ctx new_ctx = *ctx; + tree body = TREE_OPERAND (t, 0); - while (true) + do { - cxx_eval_statement_list (ctx, body, + hash_set save_exprs; + new_ctx.save_exprs = &save_exprs; + + cxx_eval_statement_list (&new_ctx, body, non_constant_p, overflow_p, jump_target); - if (returns (jump_target) || breaks (jump_target) || *non_constant_p) - break; + + /* Forget saved values of SAVE_EXPRs. */ + save_exprs.traverse(new_ctx); } + while (!returns (jump_target) && !breaks (jump_target) && !*non_constant_p); + if (breaks (jump_target)) *jump_target = NULL_TREE; + return NULL_TREE; } @@ -3114,7 +3282,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = TARGET_EXPR_INITIAL (r); if (TREE_CODE (r) == VAR_DECL) if (tree *p = ctx->values->get (r)) - r = *p; + if (*p != NULL_TREE) + r = *p; if (DECL_P (r)) { if (!ctx->quiet) @@ -3181,6 +3350,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, init = cxx_eval_constant_expression (ctx, init, false, non_constant_p, overflow_p); + /* Don't share a CONSTRUCTOR that might be changed. */ + init = unshare_expr (init); ctx->values->put (r, init); } else if (ctx == &new_ctx) @@ -3225,6 +3396,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (lval) { tree slot = TARGET_EXPR_SLOT (t); + r = unshare_expr (r); ctx->values->put (slot, r); return slot; } @@ -3269,6 +3441,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), false, non_constant_p, overflow_p); ctx->values->put (t, r); + if (ctx->save_exprs) + ctx->save_exprs->add (t); } break; @@ -3650,7 +3824,10 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, bool non_constant_p = false; bool overflow_p = false; hash_map map; - constexpr_ctx ctx = { NULL, &map, NULL, NULL, allow_non_constant, strict }; + + constexpr_ctx ctx = { NULL, &map, NULL, NULL, NULL, + allow_non_constant, strict }; + tree type = initialized_type (t); tree r = t; if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)) @@ -3758,7 +3935,9 @@ is_sub_constant_expr (tree t) bool non_constant_p = false; bool overflow_p = false; hash_map map; - constexpr_ctx ctx = { NULL, &map, NULL, NULL, true, true }; + + constexpr_ctx ctx = { NULL, &map, NULL, NULL, NULL, true, true }; + cxx_eval_constant_expression (&ctx, t, false, &non_constant_p, &overflow_p); return !non_constant_p && !overflow_p; diff --git a/contrib/gcc-5.0/gcc/cp/cp-tree.h b/contrib/gcc-5.0/gcc/cp/cp-tree.h index 6f13b01785..cb92704728 100644 --- a/contrib/gcc-5.0/gcc/cp/cp-tree.h +++ b/contrib/gcc-5.0/gcc/cp/cp-tree.h @@ -5237,6 +5237,7 @@ extern tree make_temporary_var_for_ref_to_temp (tree, tree); extern bool type_has_extended_temps (tree); extern tree strip_top_quals (tree); extern bool reference_related_p (tree, tree); +extern int remaining_arguments (tree); extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t); extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int); extern tree build_integral_nontype_arg_conv (tree, tree, tsubst_flags_t); @@ -5792,7 +5793,7 @@ extern tree get_template_parms_at_level (tree, int); extern tree get_template_innermost_arguments (const_tree); extern tree get_template_argument_pack_elems (const_tree); extern tree get_function_template_decl (const_tree); -extern tree resolve_nondeduced_context (tree); +extern tree resolve_nondeduced_context (tree, tsubst_flags_t); extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val); /* in repo.c */ diff --git a/contrib/gcc-5.0/gcc/cp/cvt.c b/contrib/gcc-5.0/gcc/cp/cvt.c index 10d50ae2a6..f4fa662e24 100644 --- a/contrib/gcc-5.0/gcc/cp/cvt.c +++ b/contrib/gcc-5.0/gcc/cp/cvt.c @@ -1260,7 +1260,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) default:; } - expr = resolve_nondeduced_context (expr); + expr = resolve_nondeduced_context (expr, complain); { tree probe = expr; diff --git a/contrib/gcc-5.0/gcc/cp/decl.c b/contrib/gcc-5.0/gcc/cp/decl.c index c9e98e96f7..ce0443ca4c 100644 --- a/contrib/gcc-5.0/gcc/cp/decl.c +++ b/contrib/gcc-5.0/gcc/cp/decl.c @@ -1991,7 +1991,31 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* For typedefs use the old type, as the new type's DECL_NAME points at newdecl, which will be ggc_freed. */ if (TREE_CODE (newdecl) == TYPE_DECL) - newtype = oldtype; + { + /* But NEWTYPE might have an attribute, honor that. */ + tree tem = TREE_TYPE (newdecl); + newtype = oldtype; + + if (TYPE_USER_ALIGN (tem)) + { + if (TYPE_ALIGN (tem) > TYPE_ALIGN (newtype)) + TYPE_ALIGN (newtype) = TYPE_ALIGN (tem); + TYPE_USER_ALIGN (newtype) = true; + } + + /* And remove the new type from the variants list. */ + if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl) + { + tree remove = TREE_TYPE (newdecl); + for (tree t = TYPE_MAIN_VARIANT (remove); ; + t = TYPE_NEXT_VARIANT (t)) + if (TYPE_NEXT_VARIANT (t) == remove) + { + TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove); + break; + } + } + } else /* Merge the data types specified in the two decls. */ newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); @@ -1999,6 +2023,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (VAR_P (newdecl)) { DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); + /* For already initialized vars, TREE_READONLY could have been + cleared in cp_finish_decl, because the var needs runtime + initialization or destruction. Make sure not to set + TREE_READONLY on it again. */ + if (DECL_INITIALIZED_P (olddecl) + && !DECL_EXTERNAL (olddecl) + && !TREE_READONLY (olddecl)) + TREE_READONLY (newdecl) = 0; DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl); DECL_NONTRIVIALLY_INITIALIZED_P (newdecl) |= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl); @@ -6127,8 +6159,11 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) return; /* We defer emission of local statics until the corresponding - DECL_EXPR is expanded. */ - defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl); + DECL_EXPR is expanded. But with constexpr its function might never + be expanded, so go ahead and tell cgraph about the variable now. */ + defer_p = ((DECL_FUNCTION_SCOPE_P (decl) + && !DECL_DECLARED_CONSTEXPR_P (DECL_CONTEXT (decl))) + || DECL_VIRTUAL_P (decl)); /* Defer template instantiations. */ if (DECL_LANG_SPECIFIC (decl) @@ -6436,7 +6471,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (TREE_CODE (d_init) == TREE_LIST) d_init = build_x_compound_expr_from_list (d_init, ELK_INIT, tf_warning_or_error); - d_init = resolve_nondeduced_context (d_init); + d_init = resolve_nondeduced_context (d_init, tf_warning_or_error); type = TREE_TYPE (decl) = do_auto_deduction (type, d_init, auto_node); if (type == error_mark_node) @@ -7360,7 +7395,8 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) /* Don't get confused by a CONSTRUCTOR for some other type. */ if (initial_value && TREE_CODE (initial_value) == CONSTRUCTOR - && !BRACE_ENCLOSED_INITIALIZER_P (initial_value)) + && !BRACE_ENCLOSED_INITIALIZER_P (initial_value) + && TREE_CODE (TREE_TYPE (initial_value)) != ARRAY_TYPE) return 1; if (initial_value) @@ -13937,7 +13973,9 @@ begin_destructor_body (void) initialize_vtbl_ptrs (current_class_ptr); finish_compound_stmt (compound_stmt); - if (flag_lifetime_dse) + if (flag_lifetime_dse + /* Clobbering an empty base is harmful if it overlays real data. */ + && !is_empty_class (current_class_type)) { /* Insert a cleanup to let the back end know that the object is dead when we exit the destructor, either normally or via exception. */ @@ -14531,8 +14569,9 @@ complete_vars (tree type) tree var = iv->decl; tree type = TREE_TYPE (var); - if (TYPE_MAIN_VARIANT (strip_array_types (type)) - == iv->incomplete_type) + if (type != error_mark_node + && (TYPE_MAIN_VARIANT (strip_array_types (type)) + == iv->incomplete_type)) { /* Complete the type of the variable. The VAR_DECL itself will be laid out in expand_expr. */ @@ -14557,7 +14596,8 @@ complete_vars (tree type) /* If DECL is of a type which needs a cleanup, build and return an expression to perform that cleanup here. Return NULL_TREE if no - cleanup need be done. */ + cleanup need be done. DECL can also be a _REF when called from + split_nonconstant_init_1. */ tree cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain) @@ -14575,7 +14615,10 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain) /* Handle "__attribute__((cleanup))". We run the cleanup function before the destructor since the destructor is what actually terminates the lifetime of the object. */ - attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl)); + if (DECL_P (decl)) + attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl)); + else + attr = NULL_TREE; if (attr) { tree id; @@ -14594,7 +14637,8 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain) ordinary FUNCTION_DECL. */ fn = lookup_name (id); arg = build_address (decl); - mark_used (decl); + if (!mark_used (decl, complain) && !(complain & tf_error)) + return error_mark_node; cleanup = cp_build_function_call_nary (fn, complain, arg, NULL_TREE); if (cleanup == error_mark_node) return error_mark_node; @@ -14634,10 +14678,12 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain) SET_EXPR_LOCATION (cleanup, UNKNOWN_LOCATION); if (cleanup - && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl)))) - /* Treat objects with destructors as used; the destructor may do - something substantive. */ - mark_used (decl); + && DECL_P (decl) + && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl))) + /* Treat objects with destructors as used; the destructor may do + something substantive. */ + && !mark_used (decl, complain) && !(complain & tf_error)) + return error_mark_node; return cleanup; } diff --git a/contrib/gcc-5.0/gcc/cp/decl2.c b/contrib/gcc-5.0/gcc/cp/decl2.c index 8d895fef43..142d493b12 100644 --- a/contrib/gcc-5.0/gcc/cp/decl2.c +++ b/contrib/gcc-5.0/gcc/cp/decl2.c @@ -2659,10 +2659,16 @@ reset_type_linkage_2 (tree type) reset_decl_linkage (ti); } for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m)) - if (TREE_CODE (m) == VAR_DECL) - reset_decl_linkage (m); + { + tree mem = STRIP_TEMPLATE (m); + if (VAR_P (mem)) + reset_decl_linkage (mem); + } for (tree m = TYPE_METHODS (type); m; m = DECL_CHAIN (m)) - reset_decl_linkage (m); + { + tree mem = STRIP_TEMPLATE (m); + reset_decl_linkage (mem); + } binding_table_foreach (CLASSTYPE_NESTED_UTDS (type), bt_reset_linkage_2, NULL); } @@ -4197,6 +4203,9 @@ decl_maybe_constant_var_p (tree decl) return false; if (DECL_DECLARED_CONSTEXPR_P (decl)) return true; + if (DECL_HAS_VALUE_EXPR_P (decl)) + /* A proxy isn't constant. */ + return false; return (CP_TYPE_CONST_NON_VOLATILE_P (type) && INTEGRAL_OR_ENUMERATION_TYPE_P (type)); } diff --git a/contrib/gcc-5.0/gcc/cp/except.c b/contrib/gcc-5.0/gcc/cp/except.c index 3ff1ce607e..2f2e3960b3 100644 --- a/contrib/gcc-5.0/gcc/cp/except.c +++ b/contrib/gcc-5.0/gcc/cp/except.c @@ -1040,7 +1040,8 @@ nothrow_libfn_p (const_tree fn) unless the system headers are playing rename tricks, and if they are, we don't want to be confused by them. */ id = DECL_NAME (fn); - return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id)); + return !!libc_name::libc_name_p (IDENTIFIER_POINTER (id), + IDENTIFIER_LENGTH (id)); } /* Returns nonzero if an exception of type FROM will be caught by a diff --git a/contrib/gcc-5.0/gcc/cp/init.c b/contrib/gcc-5.0/gcc/cp/init.c index ac11224bdf..3d79ba8e93 100644 --- a/contrib/gcc-5.0/gcc/cp/init.c +++ b/contrib/gcc-5.0/gcc/cp/init.c @@ -2079,6 +2079,11 @@ constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p) && (TREE_CODE (init) == CONSTRUCTOR || TREE_CODE (init) == STRING_CST))) break; + /* Don't return a CONSTRUCTOR for a variable with partial run-time + initialization, since it doesn't represent the entire value. */ + if (TREE_CODE (init) == CONSTRUCTOR + && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) + break; decl = unshare_expr (init); } return decl; @@ -3026,7 +3031,7 @@ build_new (vec **placement, tree type, tree nelts, if (auto_node) { tree d_init = (**init)[0]; - d_init = resolve_nondeduced_context (d_init); + d_init = resolve_nondeduced_context (d_init, complain); type = do_auto_deduction (type, d_init, auto_node); } } diff --git a/contrib/gcc-5.0/gcc/cp/method.c b/contrib/gcc-5.0/gcc/cp/method.c index 33e2f3cb52..d6fcc5b9c3 100644 --- a/contrib/gcc-5.0/gcc/cp/method.c +++ b/contrib/gcc-5.0/gcc/cp/method.c @@ -1118,7 +1118,7 @@ is_trivially_xible (enum tree_code code, tree to, tree from) static void process_subob_fn (tree fn, tree *spec_p, bool *trivial_p, bool *deleted_p, bool *constexpr_p, - bool diag, tree arg) + bool diag, tree arg, bool dtor_from_ctor = false) { if (!fn || fn == error_mark_node) goto bad; @@ -1130,7 +1130,7 @@ process_subob_fn (tree fn, tree *spec_p, bool *trivial_p, *spec_p = merge_exception_specifiers (*spec_p, raises); } - if (!trivial_fn_p (fn)) + if (!trivial_fn_p (fn) && !dtor_from_ctor) { if (trivial_p) *trivial_p = false; @@ -1163,14 +1163,17 @@ process_subob_fn (tree fn, tree *spec_p, bool *trivial_p, } /* Subroutine of synthesized_method_walk to allow recursion into anonymous - aggregates. */ + aggregates. If DTOR_FROM_CTOR is true, we're walking subobject destructors + called from a synthesized constructor, in which case we don't consider + the triviality of the subobject destructor. */ static void walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, int quals, bool copy_arg_p, bool move_p, bool assign_p, tree *spec_p, bool *trivial_p, bool *deleted_p, bool *constexpr_p, - bool diag, int flags, tsubst_flags_t complain) + bool diag, int flags, tsubst_flags_t complain, + bool dtor_from_ctor) { tree field; for (field = fields; field; field = DECL_CHAIN (field)) @@ -1287,7 +1290,7 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals, copy_arg_p, move_p, assign_p, spec_p, trivial_p, deleted_p, constexpr_p, - diag, flags, complain); + diag, flags, complain, dtor_from_ctor); continue; } @@ -1304,7 +1307,7 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain); process_subob_fn (rval, spec_p, trivial_p, deleted_p, - constexpr_p, diag, field); + constexpr_p, diag, field, dtor_from_ctor); } } @@ -1382,9 +1385,18 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, /* If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5), the - implicitly-defined default constructor is constexpr. */ + implicitly-defined default constructor is constexpr. + + The implicitly-defined copy/move assignment operator is constexpr if + - X is a literal type, and + - the assignment operator selected to copy/move each direct base class + subobject is a constexpr function, and + - for each non-static data member of X that is of class type (or array + thereof), the assignment operator selected to copy/move that member is a + constexpr function. */ if (constexpr_p) - *constexpr_p = ctor_p; + *constexpr_p = ctor_p + || (assign_p && cxx_dialect >= cxx14); move_p = false; switch (sfk) @@ -1487,7 +1499,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, dtors would be a double-fault). */ process_subob_fn (rval, NULL, NULL, deleted_p, NULL, false, - basetype); + basetype, /*dtor_from_ctor*/true); } if (check_vdtor && type_has_virtual_destructor (basetype)) @@ -1534,7 +1546,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, NULL_TREE, flags, complain); process_subob_fn (rval, NULL, NULL, deleted_p, NULL, false, - basetype); + basetype, /*dtor_from_ctor*/true); } } } @@ -1543,13 +1555,13 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals, copy_arg_p, move_p, assign_p, spec_p, trivial_p, deleted_p, constexpr_p, - diag, flags, complain); + diag, flags, complain, /*dtor_from_ctor*/false); if (ctor_p) walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier, sfk_destructor, TYPE_UNQUALIFIED, false, false, false, NULL, NULL, deleted_p, NULL, - false, flags, complain); + false, flags, complain, /*dtor_from_ctor*/true); pop_scope (scope); diff --git a/contrib/gcc-5.0/gcc/cp/optimize.c b/contrib/gcc-5.0/gcc/cp/optimize.c index a2dd880ea4..e485a6da81 100644 --- a/contrib/gcc-5.0/gcc/cp/optimize.c +++ b/contrib/gcc-5.0/gcc/cp/optimize.c @@ -670,6 +670,8 @@ maybe_clone_body (tree fn) { if (expand_or_defer_fn_1 (clone)) emit_associated_thunks (clone); + /* We didn't generate a body, so remove the empty one. */ + DECL_SAVED_TREE (clone) = NULL_TREE; } else expand_or_defer_fn (clone); diff --git a/contrib/gcc-5.0/gcc/cp/parser.c b/contrib/gcc-5.0/gcc/cp/parser.c index e6def9a2aa..03b93ab2d7 100644 --- a/contrib/gcc-5.0/gcc/cp/parser.c +++ b/contrib/gcc-5.0/gcc/cp/parser.c @@ -15682,7 +15682,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, { /* Indicate whether this class was declared as a `class' or as a `struct'. */ - if (TREE_CODE (type) == RECORD_TYPE) + if (CLASS_TYPE_P (type)) CLASSTYPE_DECLARED_CLASS (type) = (tag_type == class_type); cp_parser_check_class_key (tag_type, type); } @@ -22645,7 +22645,8 @@ cp_parser_std_attribute_spec (cp_parser *parser) static tree cp_parser_std_attribute_spec_seq (cp_parser *parser) { - tree attr_specs = NULL; + tree attr_specs = NULL_TREE; + tree attr_last = NULL_TREE; while (true) { @@ -22655,11 +22656,13 @@ cp_parser_std_attribute_spec_seq (cp_parser *parser) if (attr_spec == error_mark_node) return error_mark_node; - TREE_CHAIN (attr_spec) = attr_specs; - attr_specs = attr_spec; + if (attr_last) + TREE_CHAIN (attr_last) = attr_spec; + else + attr_specs = attr_last = attr_spec; + attr_last = tree_last (attr_last); } - attr_specs = nreverse (attr_specs); return attr_specs; } @@ -23961,6 +23964,7 @@ cp_parser_save_member_function_body (cp_parser* parser, cp_token *first; cp_token *last; tree fn; + bool function_try_block = false; /* Create the FUNCTION_DECL. */ fn = grokmethod (decl_specifiers, declarator, attributes); @@ -23981,9 +23985,43 @@ cp_parser_save_member_function_body (cp_parser* parser, /* Save away the tokens that make up the body of the function. */ first = parser->lexer->next_token; + + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_RELAXED)) + cp_lexer_consume_token (parser->lexer); + else if (cp_lexer_next_token_is_keyword (parser->lexer, + RID_TRANSACTION_ATOMIC)) + { + cp_lexer_consume_token (parser->lexer); + /* Match cp_parser_txn_attribute_opt [[ identifier ]]. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE) + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE) + && (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME) + || cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD)) + && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_SQUARE) + && cp_lexer_nth_token_is (parser->lexer, 5, CPP_CLOSE_SQUARE)) + { + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + } + else + while (cp_next_tokens_can_be_gnu_attribute_p (parser) + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN)) + { + cp_lexer_consume_token (parser->lexer); + if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0)) + break; + } + } + /* Handle function try blocks. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY)) - cp_lexer_consume_token (parser->lexer); + { + cp_lexer_consume_token (parser->lexer); + function_try_block = true; + } /* We can have braced-init-list mem-initializers before the fn body. */ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { @@ -24001,8 +24039,9 @@ cp_parser_save_member_function_body (cp_parser* parser, } cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0); /* Handle function try blocks. */ - while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH)) - cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0); + if (function_try_block) + while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH)) + cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0); last = parser->lexer->next_token; /* Save away the inline definition; we will process it when the @@ -32359,6 +32398,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok, DECL_DECLARED_INLINE_P (fndecl) = 1; DECL_IGNORED_P (fndecl) = 1; DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1; + SET_DECL_ASSEMBLER_NAME (fndecl, get_identifier ("")); DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("gnu_inline"), NULL_TREE, DECL_ATTRIBUTES (fndecl)); diff --git a/contrib/gcc-5.0/gcc/cp/pt.c b/contrib/gcc-5.0/gcc/cp/pt.c index 51cc245162..578fa20184 100644 --- a/contrib/gcc-5.0/gcc/cp/pt.c +++ b/contrib/gcc-5.0/gcc/cp/pt.c @@ -178,6 +178,7 @@ static int check_cv_quals_for_unify (int, tree, tree); static void template_parm_level_and_index (tree, int*, int*); static int unify_pack_expansion (tree, tree, tree, tree, unification_kind_t, bool, bool); +static tree copy_template_args (tree); static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); @@ -6911,11 +6912,12 @@ coerce_template_parameter_pack (tree parms, /* Convert the remaining arguments, which will be a part of the parameter pack "parm". */ + int first_pack_arg = arg_idx; for (; arg_idx < nargs; ++arg_idx) { tree arg = TREE_VEC_ELT (inner_args, arg_idx); tree actual_parm = TREE_VALUE (parm); - int pack_idx = arg_idx - parm_idx; + int pack_idx = arg_idx - first_pack_arg; if (packed_parms) { @@ -6944,12 +6946,12 @@ coerce_template_parameter_pack (tree parms, TREE_VEC_ELT (packed_args, pack_idx) = arg; } - if (arg_idx - parm_idx < TREE_VEC_LENGTH (packed_args) + if (arg_idx - first_pack_arg < TREE_VEC_LENGTH (packed_args) && TREE_VEC_LENGTH (packed_args) > 0) { if (complain & tf_error) error ("wrong number of template arguments (%d, should be %d)", - arg_idx - parm_idx, TREE_VEC_LENGTH (packed_args)); + arg_idx - first_pack_arg, TREE_VEC_LENGTH (packed_args)); return error_mark_node; } @@ -9623,11 +9625,11 @@ instantiate_class_template_1 (tree type) template friend class T::C; otherwise. */ + /* Bump processing_template_decl in case this is something like + template friend struct A::B. */ + ++processing_template_decl; friend_type = tsubst (friend_type, args, tf_warning_or_error, NULL_TREE); - /* Bump processing_template_decl for correct - dependent_type_p calculation. */ - ++processing_template_decl; if (dependent_type_p (friend_type)) adjust_processing_template_decl = true; --processing_template_decl; @@ -9998,7 +10000,8 @@ gen_elem_of_pack_expansion_instantiation (tree pattern, if (index == 0) { aps = make_argument_pack_select (arg_pack, index); - mark_used (parm); + if (!mark_used (parm, complain) && !(complain & tf_error)) + return error_mark_node; register_local_specialization (aps, parm); } else @@ -10095,12 +10098,16 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (PACK_EXPANSION_LOCAL_P (t)) arg_pack = retrieve_local_specialization (parm_pack); else + /* We can't rely on local_specializations for a parameter + name used later in a function declaration (such as in a + late-specified return type). Even if it exists, it might + have the wrong value for a recursive call. */ + need_local_specializations = true; + + if (!arg_pack) { - /* We can't rely on local_specializations for a parameter - name used later in a function declaration (such as in a - late-specified return type). Even if it exists, it might - have the wrong value for a recursive call. Just make a - dummy decl, since it's only used for its type. */ + /* This parameter pack was used in an unevaluated context. Just + make a dummy decl, since it's only used for its type. */ arg_pack = tsubst_decl (parm_pack, args, complain); if (arg_pack && DECL_PACK_P (arg_pack)) /* Partial instantiation of the parm_pack, we can't build @@ -10108,7 +10115,6 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, arg_pack = NULL_TREE; else arg_pack = make_fnparm_pack (arg_pack); - need_local_specializations = true; } } else if (TREE_CODE (parm_pack) == FIELD_DECL) @@ -10233,11 +10239,12 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* For each argument in each argument pack, substitute into the pattern. */ result = make_tree_vec (len); + tree elem_args = copy_template_args (args); for (i = 0; i < len; ++i) { t = gen_elem_of_pack_expansion_instantiation (pattern, packs, i, - args, complain, + elem_args, complain, in_decl); TREE_VEC_ELT (result, i) = t; if (t == error_mark_node) @@ -10313,6 +10320,32 @@ get_pattern_parm (tree parm, tree tmpl) return patparm; } +/* Return an exact copy of template args T that can be modified + independently. */ + +static tree +copy_template_args (tree t) +{ + if (t == error_mark_node) + return t; + + int len = TREE_VEC_LENGTH (t); + tree new_vec = make_tree_vec (len); + + for (int i = 0; i < len; ++i) + { + tree elt = TREE_VEC_ELT (t, i); + if (elt && TREE_CODE (elt) == TREE_VEC) + elt = copy_template_args (elt); + TREE_VEC_ELT (new_vec, i) = elt; + } + + NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_vec) + = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t); + + return new_vec; +} + /* Substitute ARGS into the vector or list of template arguments T. */ static tree @@ -11525,6 +11558,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* The initializer must not be expanded until it is required; see [temp.inst]. */ DECL_INITIAL (r) = NULL_TREE; + if (VAR_P (r)) + DECL_MODE (r) = VOIDmode; if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL)) SET_DECL_RTL (r, NULL); DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0; @@ -12783,15 +12818,17 @@ tsubst_baselink (tree baselink, tree object_type, point.) */ if (BASELINK_P (baselink)) fns = BASELINK_FUNCTIONS (baselink); - if (!template_id_p && !really_overloaded_fn (fns)) - mark_used (OVL_CURRENT (fns)); + if (!template_id_p && !really_overloaded_fn (fns) + && !mark_used (OVL_CURRENT (fns), complain) && !(complain & tf_error)) + return error_mark_node; /* Add back the template arguments, if present. */ if (BASELINK_P (baselink) && template_id_p) BASELINK_FUNCTIONS (baselink) - = build_nt (TEMPLATE_ID_EXPR, - BASELINK_FUNCTIONS (baselink), - template_args); + = build2 (TEMPLATE_ID_EXPR, + unknown_type_node, + BASELINK_FUNCTIONS (baselink), + template_args); /* Update the conversion operator type. */ BASELINK_OPTYPE (baselink) = optype; @@ -12899,7 +12936,8 @@ tsubst_qualified_id (tree qualified_id, tree args, check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE, scope); /* Remember that there was a reference to this entity. */ - mark_used (expr); + if (!mark_used (expr, complain) && !(complain & tf_error)) + return error_mark_node; } if (expr == error_mark_node || TREE_CODE (expr) == TREE_LIST) @@ -13009,7 +13047,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) r = ARGUMENT_PACK_SELECT_ARG (r); - mark_used (r); + if (!mark_used (r, complain) && !(complain & tf_error)) + return error_mark_node; return r; case CONST_DECL: @@ -13245,7 +13284,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) --c_inhibit_evaluation_warnings; if (TREE_CODE (expanded) == TREE_VEC) - len = TREE_VEC_LENGTH (expanded); + { + len = TREE_VEC_LENGTH (expanded); + /* Set TREE_USED for the benefit of -Wunused. */ + for (int i = 0; i < len; i++) + if (DECL_P (TREE_VEC_ELT (expanded, i))) + TREE_USED (TREE_VEC_ELT (expanded, i)) = true; + } if (expanded == error_mark_node) return error_mark_node; @@ -13531,7 +13576,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl); r = build2 (code, type, op0, op1); PTRMEM_OK_P (r) = PTRMEM_OK_P (t); - mark_used (TREE_OPERAND (r, 1)); + if (!mark_used (TREE_OPERAND (r, 1), complain) + && !(complain & tf_error)) + return error_mark_node; return r; } @@ -15092,8 +15139,9 @@ tsubst_copy_and_build (tree t, op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); /* Remember that there was a reference to this entity. */ - if (DECL_P (op1)) - mark_used (op1); + if (DECL_P (op1) + && !mark_used (op1, complain) && !(complain & tf_error)) + RETURN (error_mark_node); RETURN (build_x_arrow (input_location, op1, complain)); case NEW_EXPR: @@ -15344,8 +15392,9 @@ tsubst_copy_and_build (tree t, } /* Remember that there was a reference to this entity. */ - if (DECL_P (function)) - mark_used (function, complain); + if (DECL_P (function) + && !mark_used (function, complain) && !(complain & tf_error)) + RETURN (error_mark_node); /* Put back tf_decltype for the actual call. */ complain |= decltype_flag; @@ -15528,8 +15577,9 @@ tsubst_copy_and_build (tree t, object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); /* Remember that there was a reference to this entity. */ - if (DECL_P (object)) - mark_used (object); + if (DECL_P (object) + && !mark_used (object, complain) && !(complain & tf_error)) + RETURN (error_mark_node); object_type = TREE_TYPE (object); member = TREE_OPERAND (t, 1); @@ -15854,8 +15904,6 @@ tsubst_copy_and_build (tree t, else scope = RECUR (scope); LAMBDA_EXPR_EXTRA_SCOPE (r) = scope; - LAMBDA_EXPR_RETURN_TYPE (r) - = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl); gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (t) == NULL_TREE && LAMBDA_EXPR_PENDING_PROXIES (t) == NULL); @@ -15866,6 +15914,9 @@ tsubst_copy_and_build (tree t, declaration of the op() for later calls to lambda_function. */ complete_type (type); + if (tree fn = lambda_function (type)) + LAMBDA_EXPR_RETURN_TYPE (r) = TREE_TYPE (TREE_TYPE (fn)); + LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE; insert_pending_capture_proxies (); @@ -17344,7 +17395,7 @@ resolve_overloaded_unification (tree tparms, lvalue for the function template specialization. */ tree -resolve_nondeduced_context (tree orig_expr) +resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain) { tree expr, offset, baselink; bool addr; @@ -17427,16 +17478,16 @@ resolve_nondeduced_context (tree orig_expr) { tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (offset, 0))); - expr = build_offset_ref (base, expr, addr, tf_warning_or_error); + expr = build_offset_ref (base, expr, addr, complain); } if (addr) - expr = cp_build_addr_expr (expr, tf_warning_or_error); + expr = cp_build_addr_expr (expr, complain); return expr; } - else if (good == 0 && badargs) + else if (good == 0 && badargs && (complain & tf_error)) /* There were no good options and at least one bad one, so let the user know what the problem is. */ - instantiate_template (badfn, badargs, tf_warning_or_error); + instantiate_template (badfn, badargs, complain); } return orig_expr; } @@ -18756,7 +18807,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, /* An unresolved overload is a nondeduced context. */ if (is_overloaded_fn (parm) || type_unknown_p (parm)) return unify_success (explain_p); - gcc_assert (EXPR_P (parm)); + gcc_assert (EXPR_P (parm) || TREE_CODE (parm) == TRAIT_EXPR); /* We must be looking at an expression. This can happen with something like: @@ -19004,7 +19055,7 @@ more_specialized_fn (tree pat1, tree pat2, int len) if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION) { - int i, len2 = list_length (args2); + int i, len2 = remaining_arguments (args2); tree parmvec = make_tree_vec (1); tree argvec = make_tree_vec (len2); tree ta = args2; @@ -19028,7 +19079,7 @@ more_specialized_fn (tree pat1, tree pat2, int len) } else if (TREE_CODE (arg2) == TYPE_PACK_EXPANSION) { - int i, len1 = list_length (args1); + int i, len1 = remaining_arguments (args1); tree parmvec = make_tree_vec (1); tree argvec = make_tree_vec (len1); tree ta = args1; @@ -19469,6 +19520,38 @@ most_general_template (tree decl) return decl; } +/* True iff the TEMPLATE_DECL tmpl is a partial specialization. */ + +static bool +partial_specialization_p (tree tmpl) +{ + /* Any specialization has DECL_TEMPLATE_SPECIALIZATION. */ + if (!DECL_TEMPLATE_SPECIALIZATION (tmpl)) + return false; + if (!VAR_P (DECL_TEMPLATE_RESULT (tmpl))) + return false; + tree t = DECL_TI_TEMPLATE (tmpl); + /* A specialization that fully specializes one of the containing classes is + not a partial specialization. */ + return (list_length (DECL_TEMPLATE_PARMS (tmpl)) + == list_length (DECL_TEMPLATE_PARMS (t))); +} + +/* If TMPL is a partial specialization, return the arguments for its primary + template. */ + +static tree +impartial_args (tree tmpl, tree args) +{ + if (!partial_specialization_p (tmpl)) + return args; + + /* If TMPL is a partial specialization, we need to substitute to get + the args for the primary template. */ + return tsubst_template_args (DECL_TI_ARGS (tmpl), args, + tf_warning_or_error, tmpl); +} + /* Return the most specialized of the template partial specializations which can produce TARGET, a specialization of some class or variable template. The value returned is actually a TREE_LIST; the TREE_VALUE is @@ -20283,7 +20366,7 @@ instantiate_decl (tree d, int defer_ok, return d; gen_tmpl = most_general_template (tmpl); - gen_args = DECL_TI_ARGS (d); + gen_args = impartial_args (tmpl, DECL_TI_ARGS (d)); if (tmpl != gen_tmpl) /* We should already have the extra args. */ @@ -20328,7 +20411,10 @@ instantiate_decl (tree d, int defer_ok, else { deleted_p = false; - pattern_defined = ! DECL_IN_AGGR_P (code_pattern); + if (DECL_CLASS_SCOPE_P (code_pattern)) + pattern_defined = ! DECL_IN_AGGR_P (code_pattern); + else + pattern_defined = ! DECL_EXTERNAL (code_pattern); } /* We may be in the middle of deferred access check. Disable it now. */ @@ -20517,7 +20603,7 @@ instantiate_decl (tree d, int defer_ok, if (enter_context) pop_nested_class (); - if (variable_template_p (td)) + if (variable_template_p (gen_tmpl)) note_variable_template_instantiation (d); } else if (TREE_CODE (d) == FUNCTION_DECL && DECL_DEFAULTED_FN (code_pattern)) @@ -22127,9 +22213,9 @@ resolve_typename_type (tree type, bool only_current_p) { /* Ill-formed programs can cause infinite recursion here, so we must catch that. */ - TYPENAME_IS_RESOLVING_P (type) = 1; + TYPENAME_IS_RESOLVING_P (result) = 1; result = resolve_typename_type (result, only_current_p); - TYPENAME_IS_RESOLVING_P (type) = 0; + TYPENAME_IS_RESOLVING_P (result) = 0; } /* Qualify the resulting type. */ @@ -22341,7 +22427,7 @@ do_auto_deduction (tree type, tree init, tree auto_node) } } - init = resolve_nondeduced_context (init); + init = resolve_nondeduced_context (init, tf_warning_or_error); targs = make_tree_vec (1); if (AUTO_IS_DECLTYPE (auto_node)) diff --git a/contrib/gcc-5.0/gcc/cp/rtti.c b/contrib/gcc-5.0/gcc/cp/rtti.c index 3e941b9458..3628778f6c 100644 --- a/contrib/gcc-5.0/gcc/cp/rtti.c +++ b/contrib/gcc-5.0/gcc/cp/rtti.c @@ -255,7 +255,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain) if (error_operand_p (exp)) return error_mark_node; - exp = resolve_nondeduced_context (exp); + exp = resolve_nondeduced_context (exp, complain); /* peel back references, so they match. */ type = non_reference (TREE_TYPE (exp)); @@ -345,7 +345,7 @@ build_typeid (tree exp, tsubst_flags_t complain) /* So we need to look into the vtable of the type of exp. Make sure it isn't a null lvalue. */ exp = cp_build_addr_expr (exp, complain); - exp = stabilize_reference (exp); + exp = save_expr (exp); cond = cp_convert (boolean_type_node, exp, complain); exp = cp_build_indirect_ref (exp, RO_NULL, complain); } @@ -708,10 +708,12 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype)); td2 = get_tinfo_decl (target_type); - mark_used (td2); + if (!mark_used (td2, complain) && !(complain & tf_error)) + return error_mark_node; td2 = cp_build_addr_expr (td2, complain); td3 = get_tinfo_decl (static_type); - mark_used (td3); + if (!mark_used (td3, complain) && !(complain & tf_error)) + return error_mark_node; td3 = cp_build_addr_expr (td3, complain); /* Determine how T and V are related. */ diff --git a/contrib/gcc-5.0/gcc/cp/semantics.c b/contrib/gcc-5.0/gcc/cp/semantics.c index feba03d1c7..6705d1f97c 100644 --- a/contrib/gcc-5.0/gcc/cp/semantics.c +++ b/contrib/gcc-5.0/gcc/cp/semantics.c @@ -3119,7 +3119,8 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) tree initializer = convert_from_reference (decl); /* Mark it as used now even if the use is ill-formed. */ - mark_used (decl); + if (!mark_used (decl, complain) && !(complain & tf_error)) + return error_mark_node; /* Core issue 696: "[At the July 2009 meeting] the CWG expressed support for an approach in which a reference to a local @@ -4104,9 +4105,8 @@ expand_or_defer_fn_1 (tree fn) /* We don't want to process FN again, so pretend we've written it out, even though we haven't. */ TREE_ASM_WRITTEN (fn) = 1; - /* If this is an instantiation of a constexpr function, keep - DECL_SAVED_TREE for explain_invalid_constexpr_fn. */ - if (!is_instantiation_of_constexpr (fn)) + /* If this is a constexpr function, keep DECL_SAVED_TREE. */ + if (!DECL_DECLARED_CONSTEXPR_P (fn)) DECL_SAVED_TREE (fn) = NULL_TREE; return false; } @@ -7248,7 +7248,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, /* The type denoted by decltype(e) is defined as follows: */ - expr = resolve_nondeduced_context (expr); + expr = resolve_nondeduced_context (expr, complain); if (invalid_nonstatic_memfn_p (expr, complain)) return error_mark_node; @@ -7698,6 +7698,10 @@ apply_deduced_return_type (tree fco, tree return_type) if (TREE_TYPE (result) == return_type) return; + if (!processing_template_decl && !VOID_TYPE_P (return_type) + && !complete_type_or_else (return_type, NULL_TREE)) + return; + /* We already have a DECL_RESULT from start_preparsed_function. Now we need to redo the work it and allocate_struct_function did to reflect the new type. */ @@ -7713,8 +7717,6 @@ apply_deduced_return_type (tree fco, tree return_type) if (!processing_template_decl) { - if (!VOID_TYPE_P (TREE_TYPE (result))) - complete_type_or_else (TREE_TYPE (result), NULL_TREE); bool aggr = aggregate_value_p (result, fco); #ifdef PCC_STATIC_STRUCT_RETURN cfun->returns_pcc_struct = aggr; diff --git a/contrib/gcc-5.0/gcc/cp/tree.c b/contrib/gcc-5.0/gcc/cp/tree.c index f0a9589521..4a7008b5a2 100644 --- a/contrib/gcc-5.0/gcc/cp/tree.c +++ b/contrib/gcc-5.0/gcc/cp/tree.c @@ -1007,7 +1007,8 @@ move (tree expr) the C version of this function does not properly maintain canonical types (which are not used in C). */ tree -c_build_qualified_type (tree type, int type_quals) +c_build_qualified_type (tree type, int type_quals, tree /* orig_qual_type */, + size_t /* orig_qual_indirect */) { return cp_build_qualified_type (type, type_quals); } @@ -1345,6 +1346,9 @@ strip_typedefs (tree t) } result = make_typename_type (strip_typedefs (TYPE_CONTEXT (t)), fullname, typename_type, tf_none); + /* Handle 'typedef typename A::N N;' */ + if (typedef_variant_p (result)) + result = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (TYPE_NAME (result))); } break; case DECLTYPE_TYPE: @@ -1362,7 +1366,18 @@ strip_typedefs (tree t) } if (!result) - result = TYPE_MAIN_VARIANT (t); + { + if (typedef_variant_p (t)) + { + /* Explicitly get the underlying type, as TYPE_MAIN_VARIANT doesn't + strip typedefs with attributes. */ + result = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (TYPE_NAME (t))); + result = strip_typedefs (result); + } + else + result = TYPE_MAIN_VARIANT (t); + } + gcc_assert (!typedef_variant_p (result)); if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result) || TYPE_ALIGN (t) != TYPE_ALIGN (result)) { diff --git a/contrib/gcc-5.0/gcc/cp/typeck.c b/contrib/gcc-5.0/gcc/cp/typeck.c index 22792556c2..669f541413 100644 --- a/contrib/gcc-5.0/gcc/cp/typeck.c +++ b/contrib/gcc-5.0/gcc/cp/typeck.c @@ -1926,7 +1926,7 @@ decay_conversion (tree exp, tsubst_flags_t complain) exp = mark_rvalue_use (exp); - exp = resolve_nondeduced_context (exp); + exp = resolve_nondeduced_context (exp, complain); if (type_unknown_p (exp)) { if (complain & tf_error) @@ -2298,7 +2298,8 @@ build_class_member_access_expr (tree object, tree member, if (DECL_P (member)) { member_scope = DECL_CLASS_CONTEXT (member); - mark_used (member); + if (!mark_used (member, complain) && !(complain & tf_error)) + return error_mark_node; if (TREE_DEPRECATED (member)) warn_deprecated_use (member, NULL_TREE); } @@ -3468,7 +3469,8 @@ cp_build_function_call_vec (tree function, vec **params, if (TREE_CODE (function) == FUNCTION_DECL) { - mark_used (function); + if (!mark_used (function, complain) && !(complain & tf_error)) + return error_mark_node; fndecl = function; /* Convert anything with function type to a pointer-to-function. */ @@ -4231,7 +4233,7 @@ cp_build_binary_op (location_t location, { tree m1 = build_all_ones_cst (TREE_TYPE (op0)); tree z = build_zero_cst (TREE_TYPE (op0)); - op1 = build_conditional_expr (location, op1, z, m1, complain); + op1 = build_conditional_expr (location, op1, m1, z, complain); } else if (!COMPARISON_CLASS_P (op1)) op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1, @@ -4672,6 +4674,20 @@ cp_build_binary_op (location_t location, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + warning_at (location, OPT_Wsign_compare, "comparison between " + "types %qT and %qT", type0, type1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); @@ -5367,7 +5383,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) and the created OFFSET_REF. */ tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0))); tree fn = get_first_fn (TREE_OPERAND (arg, 1)); - mark_used (fn); + if (!mark_used (fn, complain) && !(complain & tf_error)) + return error_mark_node; if (! flag_ms_extensions) { @@ -5554,7 +5571,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) function. */ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (fn)); - mark_used (fn); + if (!mark_used (fn, complain) && !(complain & tf_error)) + return error_mark_node; val = build_address (fn); if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0))) /* Do not lose object's side effects. */ @@ -6107,8 +6125,7 @@ build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2, } expr = build_conditional_expr (loc, ifexp, op1, op2, complain); - if (processing_template_decl && expr != error_mark_node - && TREE_CODE (expr) != VEC_COND_EXPR) + if (processing_template_decl && expr != error_mark_node) { tree min = build_min_non_dep (COND_EXPR, expr, orig_ifexp, orig_op1, orig_op2); @@ -6519,7 +6536,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, result = cp_fold_convert (type, result); /* Make sure we don't fold back down to a named rvalue reference, because that would be an lvalue. */ - if (DECL_P (result)) + if (real_lvalue_p (result)) result = build1 (NON_LVALUE_EXPR, type, result); return convert_from_reference (result); } diff --git a/contrib/gcc-5.0/gcc/cp/typeck2.c b/contrib/gcc-5.0/gcc/cp/typeck2.c index a10a762351..2ae483077e 100644 --- a/contrib/gcc-5.0/gcc/cp/typeck2.c +++ b/contrib/gcc-5.0/gcc/cp/typeck2.c @@ -700,14 +700,9 @@ split_nonconstant_init_1 (tree dest, tree init) code = build_stmt (input_location, EXPR_STMT, code); code = maybe_cleanup_point_expr_void (code); add_stmt (code); - if (type_build_dtor_call (inner_type)) - { - code = (build_special_member_call - (sub, complete_dtor_identifier, NULL, inner_type, - LOOKUP_NORMAL, tf_warning_or_error)); - if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type)) - finish_eh_cleanup (code); - } + if (tree cleanup + = cxx_maybe_build_cleanup (sub, tf_warning_or_error)) + finish_eh_cleanup (cleanup); } num_split_elts++; @@ -1487,9 +1482,24 @@ process_init_constructor_union (tree type, tree init, constructor_elt *ce; int len; - /* If the initializer was empty, use default zero initialization. */ + /* If the initializer was empty, use the union's NSDMI if it has one. + Otherwise use default zero initialization. */ if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init))) - return 0; + { + for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + { + if (DECL_INITIAL (field)) + { + CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (init), + field, + get_nsdmi (field, /*in_ctor=*/false)); + break; + } + } + + if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init))) + return 0; + } len = CONSTRUCTOR_ELTS (init)->length (); if (len > 1) diff --git a/contrib/gcc-5.0/gcc/dse.c b/contrib/gcc-5.0/gcc/dse.c index 2bb20d7462..4e195c2a5c 100644 --- a/contrib/gcc-5.0/gcc/dse.c +++ b/contrib/gcc-5.0/gcc/dse.c @@ -1571,14 +1571,9 @@ record_store (rtx body, bb_info_t bb_info) mem_addr = base->val_rtx; else { - group_info_t group - = rtx_group_vec[group_id]; + group_info_t group = rtx_group_vec[group_id]; mem_addr = group->canon_base_addr; } - /* get_addr can only handle VALUE but cannot handle expr like: - VALUE + OFFSET, so call get_addr to get original addr for - mem_addr before plus_constant. */ - mem_addr = get_addr (mem_addr); if (offset) mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset); } @@ -1670,10 +1665,9 @@ record_store (rtx body, bb_info_t bb_info) the value of store_info. If it is, set the rhs to NULL to keep it from being used to remove a load. */ { - if (canon_true_dependence (s_info->mem, - GET_MODE (s_info->mem), - s_info->mem_addr, - mem, mem_addr)) + if (canon_output_dependence (s_info->mem, true, + mem, GET_MODE (mem), + mem_addr)) { s_info->rhs = NULL; s_info->const_rhs = NULL; @@ -2188,14 +2182,9 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) mem_addr = base->val_rtx; else { - group_info_t group - = rtx_group_vec[group_id]; + group_info_t group = rtx_group_vec[group_id]; mem_addr = group->canon_base_addr; } - /* get_addr can only handle VALUE but cannot handle expr like: - VALUE + OFFSET, so call get_addr to get original addr for - mem_addr before plus_constant. */ - mem_addr = get_addr (mem_addr); if (offset) mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset); } @@ -2626,6 +2615,8 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn) active_local_stores = insn_info; } } + else + clear_rhs_from_active_local_stores (); } } else if (SIBLING_CALL_P (insn) && reload_completed) diff --git a/contrib/gcc-5.0/gcc/dwarf2out.c b/contrib/gcc-5.0/gcc/dwarf2out.c index 3614c10780..6808cc1591 100644 --- a/contrib/gcc-5.0/gcc/dwarf2out.c +++ b/contrib/gcc-5.0/gcc/dwarf2out.c @@ -16255,7 +16255,7 @@ native_encode_initializer (tree init, unsigned char *array, int size) fieldsize = tree_to_shwi (DECL_SIZE_UNIT (field)); pos = int_byte_position (field); gcc_assert (pos + fieldsize <= size); - if (val + if (val && fieldsize != 0 && !native_encode_initializer (val, array + pos, fieldsize)) return false; } @@ -19129,7 +19129,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) DW_TAG_common_block and DW_TAG_variable. */ loc = loc_list_from_tree (com_decl, 2, NULL); } - else if (DECL_EXTERNAL (decl)) + else if (DECL_EXTERNAL (decl_or_origin)) add_AT_flag (com_die, DW_AT_declaration, 1); if (want_pubnames ()) add_pubname_string (cnam, com_die); /* ??? needed? */ @@ -19144,9 +19144,9 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) remove_AT (com_die, DW_AT_declaration); } var_die = new_die (DW_TAG_variable, com_die, decl); - add_name_and_src_coords_attributes (var_die, decl); - add_type_attribute (var_die, TREE_TYPE (decl), decl_quals (decl), - context_die); + add_name_and_src_coords_attributes (var_die, decl_or_origin); + add_type_attribute (var_die, TREE_TYPE (decl_or_origin), + decl_quals (decl_or_origin), context_die); add_AT_flag (var_die, DW_AT_external, 1); if (loc) { @@ -19167,9 +19167,10 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) } add_AT_location_description (var_die, DW_AT_location, loc); } - else if (DECL_EXTERNAL (decl)) + else if (DECL_EXTERNAL (decl_or_origin)) add_AT_flag (var_die, DW_AT_declaration, 1); - equate_decl_number_to_die (decl, var_die); + if (decl) + equate_decl_number_to_die (decl, var_die); return; } @@ -20290,9 +20291,10 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, /* We are going to output a DIE to represent the unqualified version of this type (i.e. without any const or volatile qualifiers) so get the main variant (i.e. the unqualified version) of this type - now. (Vectors are special because the debugging info is in the + now. (Vectors and arrays are special because the debugging info is in the cloned type itself). */ - if (TREE_CODE (type) != VECTOR_TYPE) + if (TREE_CODE (type) != VECTOR_TYPE + && TREE_CODE (type) != ARRAY_TYPE) type = type_main_variant (type); /* If this is an array type with hidden descriptor, handle it first. */ diff --git a/contrib/gcc-5.0/gcc/emit-rtl.c b/contrib/gcc-5.0/gcc/emit-rtl.c index 00ba64e1e6..5b749ac97b 100644 --- a/contrib/gcc-5.0/gcc/emit-rtl.c +++ b/contrib/gcc-5.0/gcc/emit-rtl.c @@ -5256,7 +5256,8 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum) { case REG_EQUAL: case REG_EQUIV: - if (!set_for_reg_notes (insn)) + /* We need to support the REG_EQUAL on USE trick of find_reloads. */ + if (!set_for_reg_notes (insn) && GET_CODE (PATTERN (insn)) != USE) return NULL_RTX; /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes. diff --git a/contrib/gcc-5.0/gcc/explow.c b/contrib/gcc-5.0/gcc/explow.c index de446a903f..9c766e1f2e 100644 --- a/contrib/gcc-5.0/gcc/explow.c +++ b/contrib/gcc-5.0/gcc/explow.c @@ -281,12 +281,14 @@ break_out_memory_refs (rtx x) which way). We take advantage of the fact that pointers are not allowed to overflow by commuting arithmetic operations over conversions so that address arithmetic insns can be used. IN_CONST is true if this conversion is inside - a CONST. */ + a CONST. NO_EMIT is true if no insns should be emitted, and instead + it should return NULL if it can't be simplified without emitting insns. */ -static rtx +rtx convert_memory_address_addr_space_1 (machine_mode to_mode ATTRIBUTE_UNUSED, rtx x, addr_space_t as ATTRIBUTE_UNUSED, - bool in_const ATTRIBUTE_UNUSED) + bool in_const ATTRIBUTE_UNUSED, + bool no_emit ATTRIBUTE_UNUSED) { #ifndef POINTERS_EXTEND_UNSIGNED gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode); @@ -332,19 +334,16 @@ convert_memory_address_addr_space_1 (machine_mode to_mode ATTRIBUTE_UNUSED, temp = gen_rtx_LABEL_REF (to_mode, LABEL_REF_LABEL (x)); LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x); return temp; - break; case SYMBOL_REF: temp = shallow_copy_rtx (x); PUT_MODE (temp, to_mode); return temp; - break; case CONST: - return gen_rtx_CONST (to_mode, - convert_memory_address_addr_space_1 - (to_mode, XEXP (x, 0), as, true)); - break; + temp = convert_memory_address_addr_space_1 (to_mode, XEXP (x, 0), as, + true, no_emit); + return temp ? gen_rtx_CONST (to_mode, temp) : temp; case PLUS: case MULT: @@ -360,18 +359,25 @@ convert_memory_address_addr_space_1 (machine_mode to_mode ATTRIBUTE_UNUSED, && CONST_INT_P (XEXP (x, 1)) && ((in_const && POINTERS_EXTEND_UNSIGNED != 0) || XEXP (x, 1) == convert_memory_address_addr_space_1 - (to_mode, XEXP (x, 1), as, in_const) + (to_mode, XEXP (x, 1), as, in_const, + no_emit) || POINTERS_EXTEND_UNSIGNED < 0))) - return gen_rtx_fmt_ee (GET_CODE (x), to_mode, - convert_memory_address_addr_space_1 - (to_mode, XEXP (x, 0), as, in_const), - XEXP (x, 1)); + { + temp = convert_memory_address_addr_space_1 (to_mode, XEXP (x, 0), + as, in_const, no_emit); + return (temp ? gen_rtx_fmt_ee (GET_CODE (x), to_mode, + temp, XEXP (x, 1)) + : temp); + } break; default: break; } + if (no_emit) + return NULL_RTX; + return convert_modes (to_mode, from_mode, x, POINTERS_EXTEND_UNSIGNED); #endif /* defined(POINTERS_EXTEND_UNSIGNED) */ @@ -386,7 +392,7 @@ convert_memory_address_addr_space_1 (machine_mode to_mode ATTRIBUTE_UNUSED, rtx convert_memory_address_addr_space (machine_mode to_mode, rtx x, addr_space_t as) { - return convert_memory_address_addr_space_1 (to_mode, x, as, false); + return convert_memory_address_addr_space_1 (to_mode, x, as, false, false); } diff --git a/contrib/gcc-5.0/gcc/expr.c b/contrib/gcc-5.0/gcc/expr.c index 5c095507f4..d72c05375a 100644 --- a/contrib/gcc-5.0/gcc/expr.c +++ b/contrib/gcc-5.0/gcc/expr.c @@ -6100,6 +6100,13 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) type = lang_hooks.types.type_for_mode (word_mode, TYPE_UNSIGNED (type)); value = fold_convert (type, value); + /* Make sure the bits beyond the original bitsize are zero + so that we can correctly avoid extra zeroing stores in + later constructor elements. */ + tree bitsize_mask + = wide_int_to_tree (type, wi::mask (bitsize, false, + BITS_PER_WORD)); + value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask); } if (BYTES_BIG_ENDIAN) diff --git a/contrib/gcc-5.0/gcc/fold-const.c b/contrib/gcc-5.0/gcc/fold-const.c index 029bcb662f..fa58a5a6aa 100644 --- a/contrib/gcc-5.0/gcc/fold-const.c +++ b/contrib/gcc-5.0/gcc/fold-const.c @@ -129,7 +129,8 @@ enum comparison_code { static bool negate_mathfn_p (enum built_in_function); static bool negate_expr_p (tree); static tree negate_expr (tree); -static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int); +static tree split_tree (location_t, tree, tree, enum tree_code, + tree *, tree *, tree *, int); static tree associate_trees (location_t, tree, tree, enum tree_code, tree); static enum comparison_code comparison_to_compcode (enum tree_code); static enum tree_code compcode_to_comparison (enum comparison_code); @@ -819,7 +820,10 @@ negate_expr (tree t) literal for which we use *MINUS_LITP instead. If NEGATE_P is true, we are negating all of IN, again except a literal - for which we use *MINUS_LITP instead. + for which we use *MINUS_LITP instead. If a variable part is of pointer + type, it is negated after converting to TYPE. This prevents us from + generating illegal MINUS pointer expression. LOC is the location of + the converted variable part. If IN is itself a literal or constant, return it as appropriate. @@ -827,8 +831,8 @@ negate_expr (tree t) same type as IN, but they will have the same signedness and mode. */ static tree -split_tree (tree in, enum tree_code code, tree *conp, tree *litp, - tree *minus_litp, int negate_p) +split_tree (location_t loc, tree in, tree type, enum tree_code code, + tree *conp, tree *litp, tree *minus_litp, int negate_p) { tree var = 0; @@ -884,8 +888,12 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp, *minus_litp = *litp, *litp = 0; if (neg_conp_p) *conp = negate_expr (*conp); - if (neg_var_p) - var = negate_expr (var); + if (neg_var_p && var) + { + /* Convert to TYPE before negating. */ + var = fold_convert_loc (loc, type, var); + var = negate_expr (var); + } } else if (TREE_CODE (in) == BIT_NOT_EXPR && code == PLUS_EXPR) @@ -906,7 +914,12 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp, else if (*minus_litp) *litp = *minus_litp, *minus_litp = 0; *conp = negate_expr (*conp); - var = negate_expr (var); + if (var) + { + /* Convert to TYPE before negating. */ + var = fold_convert_loc (loc, type, var); + var = negate_expr (var); + } } return var; @@ -2191,7 +2204,6 @@ fold_convertible_p (const_tree type, const_tree arg) case REAL_TYPE: case FIXED_POINT_TYPE: - case COMPLEX_TYPE: case VECTOR_TYPE: case VOID_TYPE: return TREE_CODE (type) == TREE_CODE (orig); @@ -5983,8 +5995,15 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, or (for divide and modulus) if it is a multiple of our constant. */ if (code == MULT_EXPR || wi::multiple_of_p (t, c, TYPE_SIGN (type))) - return const_binop (code, fold_convert (ctype, t), - fold_convert (ctype, c)); + { + tree tem = const_binop (code, fold_convert (ctype, t), + fold_convert (ctype, c)); + /* If the multiplication overflowed, we lost information on it. + See PR68142 and PR69845. */ + if (TREE_OVERFLOW (tem)) + return NULL_TREE; + return tem; + } break; CASE_CONVERT: case NON_LVALUE_EXPR: @@ -6241,18 +6260,19 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, bool overflow_p = false; bool overflow_mul_p; signop sign = TYPE_SIGN (ctype); - wide_int mul = wi::mul (op1, c, sign, &overflow_mul_p); + unsigned prec = TYPE_PRECISION (ctype); + wide_int mul = wi::mul (wide_int::from (op1, prec, + TYPE_SIGN (TREE_TYPE (op1))), + wide_int::from (c, prec, + TYPE_SIGN (TREE_TYPE (c))), + sign, &overflow_mul_p); overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1); if (overflow_mul_p && ((sign == UNSIGNED && tcode != MULT_EXPR) || sign == SIGNED)) overflow_p = true; if (!overflow_p) - { - mul = wide_int::from (mul, TYPE_PRECISION (ctype), - TYPE_SIGN (TREE_TYPE (op1))); - return fold_build2 (tcode, ctype, fold_convert (ctype, op0), - wide_int_to_tree (ctype, mul)); - } + return fold_build2 (tcode, ctype, fold_convert (ctype, op0), + wide_int_to_tree (ctype, mul)); } /* If these operations "cancel" each other, we have the main @@ -8731,20 +8751,6 @@ pointer_may_wrap_p (tree base, tree offset, HOST_WIDE_INT bitpos) return total.to_uhwi () > (unsigned HOST_WIDE_INT) size; } -/* Return the HOST_WIDE_INT least significant bits of T, a sizetype - kind INTEGER_CST. This makes sure to properly sign-extend the - constant. */ - -static HOST_WIDE_INT -size_low_cst (const_tree t) -{ - HOST_WIDE_INT w = TREE_INT_CST_ELT (t, 0); - int prec = TYPE_PRECISION (TREE_TYPE (t)); - if (prec < HOST_BITS_PER_WIDE_INT) - return sext_hwi (w, prec); - return w; -} - /* Subroutine of fold_binary. This routine performs all of the transformations that are common to the equality/inequality operators (EQ_EXPR and NE_EXPR) and the ordering operators @@ -8889,18 +8895,29 @@ fold_comparison (location_t loc, enum tree_code code, tree type, STRIP_SIGN_NOPS (base0); if (TREE_CODE (base0) == ADDR_EXPR) { - base0 = TREE_OPERAND (base0, 0); - indirect_base0 = true; + base0 + = get_inner_reference (TREE_OPERAND (base0, 0), + &bitsize, &bitpos0, &offset0, &mode, + &unsignedp, &volatilep, false); + if (TREE_CODE (base0) == INDIRECT_REF) + base0 = TREE_OPERAND (base0, 0); + else + indirect_base0 = true; } - offset0 = TREE_OPERAND (arg0, 1); - if (tree_fits_shwi_p (offset0)) + if (offset0 == NULL_TREE || integer_zerop (offset0)) + offset0 = TREE_OPERAND (arg0, 1); + else + offset0 = size_binop (PLUS_EXPR, offset0, + TREE_OPERAND (arg0, 1)); + if (TREE_CODE (offset0) == INTEGER_CST) { - HOST_WIDE_INT off = size_low_cst (offset0); - if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off) - * BITS_PER_UNIT) - / BITS_PER_UNIT == (HOST_WIDE_INT) off) + offset_int tem = wi::sext (wi::to_offset (offset0), + TYPE_PRECISION (sizetype)); + tem = wi::lshift (tem, LOG2_BITS_PER_UNIT); + tem += bitpos0; + if (wi::fits_shwi_p (tem)) { - bitpos0 = off * BITS_PER_UNIT; + bitpos0 = tem.to_shwi (); offset0 = NULL_TREE; } } @@ -8923,18 +8940,29 @@ fold_comparison (location_t loc, enum tree_code code, tree type, STRIP_SIGN_NOPS (base1); if (TREE_CODE (base1) == ADDR_EXPR) { - base1 = TREE_OPERAND (base1, 0); - indirect_base1 = true; + base1 + = get_inner_reference (TREE_OPERAND (base1, 0), + &bitsize, &bitpos1, &offset1, &mode, + &unsignedp, &volatilep, false); + if (TREE_CODE (base1) == INDIRECT_REF) + base1 = TREE_OPERAND (base1, 0); + else + indirect_base1 = true; } - offset1 = TREE_OPERAND (arg1, 1); - if (tree_fits_shwi_p (offset1)) + if (offset1 == NULL_TREE || integer_zerop (offset1)) + offset1 = TREE_OPERAND (arg1, 1); + else + offset1 = size_binop (PLUS_EXPR, offset1, + TREE_OPERAND (arg1, 1)); + if (TREE_CODE (offset1) == INTEGER_CST) { - HOST_WIDE_INT off = size_low_cst (offset1); - if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off) - * BITS_PER_UNIT) - / BITS_PER_UNIT == (HOST_WIDE_INT) off) + offset_int tem = wi::sext (wi::to_offset (offset1), + TYPE_PRECISION (sizetype)); + tem = wi::lshift (tem, LOG2_BITS_PER_UNIT); + tem += bitpos1; + if (wi::fits_shwi_p (tem)) { - bitpos1 = off * BITS_PER_UNIT; + bitpos1 = tem.to_shwi (); offset1 = NULL_TREE; } } @@ -10364,9 +10392,10 @@ fold_binary_loc (location_t loc, then the result with variables. This increases the chances of literals being recombined later and of generating relocatable expressions for the sum of a constant and literal. */ - var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0); - var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1, - code == MINUS_EXPR); + var0 = split_tree (loc, arg0, type, code, + &con0, &lit0, &minus_lit0, 0); + var1 = split_tree (loc, arg1, type, code, + &con1, &lit1, &minus_lit1, code == MINUS_EXPR); /* Recombine MINUS_EXPR operands by using PLUS_EXPR. */ if (code == MINUS_EXPR) @@ -12091,11 +12120,15 @@ fold_binary_loc (location_t loc, || TREE_CODE (arg0) == BIT_IOR_EXPR || TREE_CODE (arg0) == BIT_XOR_EXPR) && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) - return fold_build2_loc (loc, TREE_CODE (arg0), type, - fold_build2_loc (loc, code, type, - TREE_OPERAND (arg0, 0), arg1), - fold_build2_loc (loc, code, type, - TREE_OPERAND (arg0, 1), arg1)); + { + tree arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); + tree arg01 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1)); + return fold_build2_loc (loc, TREE_CODE (arg0), type, + fold_build2_loc (loc, code, type, + arg00, arg1), + fold_build2_loc (loc, code, type, + arg01, arg1)); + } /* Two consecutive rotates adding up to the some integer multiple of the precision of the type can be ignored. */ @@ -12104,7 +12137,7 @@ fold_binary_loc (location_t loc, && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST && wi::umod_trunc (wi::add (arg1, TREE_OPERAND (arg0, 1)), prec) == 0) - return TREE_OPERAND (arg0, 0); + return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); /* Fold (X & C2) << C1 into (X << C1) & (C2 << C1) (X & C2) >> C1 into (X >> C1) & (C2 >> C1) @@ -12375,12 +12408,27 @@ fold_binary_loc (location_t loc, || POINTER_TYPE_P (TREE_TYPE (arg0)))) { tree val = TREE_OPERAND (arg0, 1); - return omit_two_operands_loc (loc, type, - fold_build2_loc (loc, code, type, - val, - build_int_cst (TREE_TYPE (val), - 0)), - TREE_OPERAND (arg0, 0), arg1); + val = fold_build2_loc (loc, code, type, val, + build_int_cst (TREE_TYPE (val), 0)); + return omit_two_operands_loc (loc, type, val, + TREE_OPERAND (arg0, 0), arg1); + } + + /* Transform comparisons of the form X CMP X +- Y to Y CMP 0. */ + if ((TREE_CODE (arg1) == PLUS_EXPR + || TREE_CODE (arg1) == POINTER_PLUS_EXPR + || TREE_CODE (arg1) == MINUS_EXPR) + && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg1, + 0)), + arg0, 0) + && (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) + || POINTER_TYPE_P (TREE_TYPE (arg1)))) + { + tree val = TREE_OPERAND (arg1, 1); + val = fold_build2_loc (loc, code, type, val, + build_int_cst (TREE_TYPE (val), 0)); + return omit_two_operands_loc (loc, type, val, + TREE_OPERAND (arg1, 0), arg0); } /* Transform comparisons of the form C - X CMP X if C % 2 == 1. */ @@ -12390,12 +12438,22 @@ fold_binary_loc (location_t loc, 1)), arg1, 0) && wi::extract_uhwi (TREE_OPERAND (arg0, 0), 0, 1) == 1) - { - return omit_two_operands_loc (loc, type, - code == NE_EXPR - ? boolean_true_node : boolean_false_node, - TREE_OPERAND (arg0, 1), arg1); - } + return omit_two_operands_loc (loc, type, + code == NE_EXPR + ? boolean_true_node : boolean_false_node, + TREE_OPERAND (arg0, 1), arg1); + + /* Transform comparisons of the form X CMP C - X if C % 2 == 1. */ + if (TREE_CODE (arg1) == MINUS_EXPR + && TREE_CODE (TREE_OPERAND (arg1, 0)) == INTEGER_CST + && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg1, + 1)), + arg0, 0) + && wi::extract_uhwi (TREE_OPERAND (arg1, 0), 0, 1) == 1) + return omit_two_operands_loc (loc, type, + code == NE_EXPR + ? boolean_true_node : boolean_false_node, + TREE_OPERAND (arg1, 1), arg0); /* Convert ABS_EXPR == 0 or ABS_EXPR != 0 to x == 0 or x != 0. */ if (TREE_CODE (arg0) == ABS_EXPR diff --git a/contrib/gcc-5.0/gcc/fwprop.c b/contrib/gcc-5.0/gcc/fwprop.c index fc64ec95e6..bc837c44bd 100644 --- a/contrib/gcc-5.0/gcc/fwprop.c +++ b/contrib/gcc-5.0/gcc/fwprop.c @@ -1013,10 +1013,27 @@ try_fwprop_subst (df_ref use, rtx *loc, rtx new_rtx, rtx_insn *def_insn, making a new one if one does not already exist. */ if (set_reg_equal) { - if (dump_file) - fprintf (dump_file, " Setting REG_EQUAL note\n"); + /* If there are any paradoxical SUBREGs, don't add REG_EQUAL note, + because the bits in there can be anything and so might not + match the REG_EQUAL note content. See PR70574. */ + subrtx_var_iterator::array_type array; + FOR_EACH_SUBRTX_VAR (iter, array, *loc, NONCONST) + { + rtx x = *iter; + if (SUBREG_P (x) && paradoxical_subreg_p (x)) + { + set_reg_equal = false; + break; + } + } - note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (new_rtx)); + if (set_reg_equal) + { + if (dump_file) + fprintf (dump_file, " Setting REG_EQUAL note\n"); + + note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (new_rtx)); + } } } @@ -1314,14 +1331,19 @@ forward_propagate_and_simplify (df_ref use, rtx_insn *def_insn, rtx def_set) that isn't mentioned in USE_SET, as the note would be invalid otherwise. We also don't want to install a note if we are merely propagating a pseudo since verifying that this pseudo isn't dead - is a pain; moreover such a note won't help anything. */ + is a pain; moreover such a note won't help anything. + If the use is a paradoxical subreg, make sure we don't add a + REG_EQUAL note for it, because it is not equivalent, it is one + possible value for it, but we can't rely on it holding that value. + See PR70574. */ set_reg_equal = (note == NULL_RTX && REG_P (SET_DEST (use_set)) && !REG_P (src) && !(GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))) && !reg_mentioned_p (SET_DEST (use_set), - SET_SRC (use_set))); + SET_SRC (use_set)) + && !paradoxical_subreg_p (DF_REF_REG (use))); } if (GET_MODE (*loc) == VOIDmode) diff --git a/contrib/gcc-5.0/gcc/gcc.c b/contrib/gcc-5.0/gcc/gcc.c index d956c36b15..64d2e34c86 100644 --- a/contrib/gcc-5.0/gcc/gcc.c +++ b/contrib/gcc-5.0/gcc/gcc.c @@ -5148,8 +5148,9 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) if (files_differ) #endif { - temp_filename = save_string (temp_filename, - temp_filename_length + 1); + temp_filename + = save_string (temp_filename, + temp_filename_length - 1); obstack_grow (&obstack, temp_filename, temp_filename_length); arg_going = 1; diff --git a/contrib/gcc-5.0/gcc/gcse.c b/contrib/gcc-5.0/gcc/gcse.c index 37aac6ae98..0f6d456ab3 100644 --- a/contrib/gcc-5.0/gcc/gcse.c +++ b/contrib/gcc-5.0/gcc/gcse.c @@ -3830,10 +3830,8 @@ compute_ld_motion_mems (void) { rtx src = SET_SRC (PATTERN (insn)); rtx dest = SET_DEST (PATTERN (insn)); - rtx note = find_reg_equal_equiv_note (insn); - rtx src_eq; - /* Check for a simple LOAD... */ + /* Check for a simple load. */ if (MEM_P (src) && simple_mem (src)) { ptr = ldst_entry (src); @@ -3848,12 +3846,11 @@ compute_ld_motion_mems (void) invalidate_any_buried_refs (src); } - if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL) - src_eq = XEXP (note, 0); - else - src_eq = NULL_RTX; - - if (src_eq != NULL_RTX + /* Check for a simple load through a REG_EQUAL note. */ + rtx note = find_reg_equal_equiv_note (insn), src_eq; + if (note + && REG_NOTE_KIND (note) == REG_EQUAL + && (src_eq = XEXP (note, 0)) && !(MEM_P (src_eq) && simple_mem (src_eq))) invalidate_any_buried_refs (src_eq); @@ -3876,7 +3873,17 @@ compute_ld_motion_mems (void) } } else - invalidate_any_buried_refs (PATTERN (insn)); + { + /* Invalidate all MEMs in the pattern and... */ + invalidate_any_buried_refs (PATTERN (insn)); + + /* ...in REG_EQUAL notes for PARALLELs with single SET. */ + rtx note = find_reg_equal_equiv_note (insn), src_eq; + if (note + && REG_NOTE_KIND (note) == REG_EQUAL + && (src_eq = XEXP (note, 0))) + invalidate_any_buried_refs (src_eq); + } } } } diff --git a/contrib/gcc-5.0/gcc/genpreds.c b/contrib/gcc-5.0/gcc/genpreds.c index 1eb3368cf6..1dcb76936e 100644 --- a/contrib/gcc-5.0/gcc/genpreds.c +++ b/contrib/gcc-5.0/gcc/genpreds.c @@ -640,12 +640,14 @@ struct constraint_data const char *regclass; /* for register constraints */ rtx exp; /* for other constraints */ unsigned int lineno; /* line of definition */ - unsigned int is_register : 1; - unsigned int is_const_int : 1; - unsigned int is_const_dbl : 1; - unsigned int is_extra : 1; - unsigned int is_memory : 1; - unsigned int is_address : 1; + unsigned int is_register : 1; + unsigned int is_const_int : 1; + unsigned int is_const_dbl : 1; + unsigned int is_extra : 1; + unsigned int is_memory : 1; + unsigned int is_address : 1; + unsigned int maybe_allows_reg : 1; + unsigned int maybe_allows_mem : 1; }; /* Overview of all constraints beginning with a given letter. */ @@ -691,6 +693,9 @@ static unsigned int satisfied_start; static unsigned int const_int_start, const_int_end; static unsigned int memory_start, memory_end; static unsigned int address_start, address_end; +static unsigned int maybe_allows_none_start, maybe_allows_none_end; +static unsigned int maybe_allows_reg_start, maybe_allows_reg_end; +static unsigned int maybe_allows_mem_start, maybe_allows_mem_end; /* Convert NAME, which contains angle brackets and/or underscores, to a string that can be used as part of a C identifier. The string @@ -711,6 +716,34 @@ mangle (const char *name) return XOBFINISH (rtl_obstack, const char *); } +/* Return a bitmask, bit 1 if EXP maybe allows a REG/SUBREG, 2 if EXP + maybe allows a MEM. Bits should be clear only when we are sure it + will not allow a REG/SUBREG or a MEM. */ +static int +compute_maybe_allows (rtx exp) +{ + switch (GET_CODE (exp)) + { + case IF_THEN_ELSE: + /* Conservative answer is like IOR, of the THEN and ELSE branches. */ + return compute_maybe_allows (XEXP (exp, 1)) + | compute_maybe_allows (XEXP (exp, 2)); + case AND: + return compute_maybe_allows (XEXP (exp, 0)) + & compute_maybe_allows (XEXP (exp, 1)); + case IOR: + return compute_maybe_allows (XEXP (exp, 0)) + | compute_maybe_allows (XEXP (exp, 1)); + case MATCH_CODE: + if (*XSTR (exp, 1) == '\0') + return (strstr (XSTR (exp, 0), "reg") != NULL ? 1 : 0) + | (strstr (XSTR (exp, 0), "mem") != NULL ? 2 : 0); + /* FALLTHRU */ + default: + return 3; + } +} + /* Add one constraint, of any sort, to the tables. NAME is its name; REGCLASS is the register class, if any; EXP is the expression to test, if any; IS_MEMORY and IS_ADDRESS indicate memory and address @@ -866,6 +899,11 @@ add_constraint (const char *name, const char *regclass, c->is_extra = !(regclass || is_const_int || is_const_dbl); c->is_memory = is_memory; c->is_address = is_address; + int maybe_allows = 3; + if (exp) + maybe_allows = compute_maybe_allows (exp); + c->maybe_allows_reg = (maybe_allows & 1) != 0; + c->maybe_allows_mem = (maybe_allows & 2) != 0; c->next_this_letter = *slot; *slot = c; @@ -940,8 +978,30 @@ choose_enum_order (void) enum_order[next++] = c; address_end = next; + maybe_allows_none_start = next; + FOR_ALL_CONSTRAINTS (c) + if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address + && !c->maybe_allows_reg && !c->maybe_allows_mem) + enum_order[next++] = c; + maybe_allows_none_end = next; + + maybe_allows_reg_start = next; + FOR_ALL_CONSTRAINTS (c) + if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address + && c->maybe_allows_reg && !c->maybe_allows_mem) + enum_order[next++] = c; + maybe_allows_reg_end = next; + + maybe_allows_mem_start = next; + FOR_ALL_CONSTRAINTS (c) + if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address + && !c->maybe_allows_reg && c->maybe_allows_mem) + enum_order[next++] = c; + maybe_allows_mem_end = next; + FOR_ALL_CONSTRAINTS (c) - if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address) + if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address + && c->maybe_allows_reg && c->maybe_allows_mem) enum_order[next++] = c; gcc_assert (next == num_constraints); } @@ -1229,6 +1289,41 @@ write_range_function (const char *name, unsigned int start, unsigned int end) "}\n\n", name); } +/* Write a definition for insn_extra_constraint_allows_reg_mem function. */ +static void +write_allows_reg_mem_function (void) +{ + printf ("static inline void\n" + "insn_extra_constraint_allows_reg_mem (enum constraint_num c,\n" + "\t\t\t\t bool *allows_reg, bool *allows_mem)\n" + "{\n"); + if (maybe_allows_none_start != maybe_allows_none_end) + printf (" if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n" + " return;\n", + enum_order[maybe_allows_none_start]->c_name, + enum_order[maybe_allows_none_end - 1]->c_name); + if (maybe_allows_reg_start != maybe_allows_reg_end) + printf (" if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n" + " {\n" + " *allows_reg = true;\n" + " return;\n" + " }\n", + enum_order[maybe_allows_reg_start]->c_name, + enum_order[maybe_allows_reg_end - 1]->c_name); + if (maybe_allows_mem_start != maybe_allows_mem_end) + printf (" if (c >= CONSTRAINT_%s && c <= CONSTRAINT_%s)\n" + " {\n" + " *allows_mem = true;\n" + " return;\n" + " }\n", + enum_order[maybe_allows_mem_start]->c_name, + enum_order[maybe_allows_mem_end - 1]->c_name); + printf (" (void) c;\n" + " *allows_reg = true;\n" + " *allows_mem = true;\n" + "}\n\n"); +} + /* VEC is a list of key/value pairs, with the keys being lower bounds of a range. Output a decision tree that handles the keys covered by [VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s. @@ -1326,6 +1421,7 @@ write_tm_preds_h (void) memory_start, memory_end); write_range_function ("insn_extra_address_constraint", address_start, address_end); + write_allows_reg_mem_function (); if (constraint_max_namelen > 1) { diff --git a/contrib/gcc-5.0/gcc/gimple-expr.c b/contrib/gcc-5.0/gcc/gimple-expr.c index efc93b7a55..22cb5add1f 100644 --- a/contrib/gcc-5.0/gcc/gimple-expr.c +++ b/contrib/gcc-5.0/gcc/gimple-expr.c @@ -387,6 +387,11 @@ copy_var_decl (tree var, tree name, tree type) TREE_USED (copy) = 1; DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var); + if (DECL_USER_ALIGN (var)) + { + DECL_ALIGN (copy) = DECL_ALIGN (var); + DECL_USER_ALIGN (copy) = 1; + } return copy; } @@ -565,8 +570,8 @@ create_tmp_reg_fn (struct function *fn, tree type, const char *prefix) *OP1_P, *OP2_P and *OP3_P respectively. */ void -extract_ops_from_tree_1 (tree expr, enum tree_code *subcode_p, tree *op1_p, - tree *op2_p, tree *op3_p) +extract_ops_from_tree (tree expr, enum tree_code *subcode_p, tree *op1_p, + tree *op2_p, tree *op3_p) { enum gimple_rhs_class grhs_class; diff --git a/contrib/gcc-5.0/gcc/gimple-expr.h b/contrib/gcc-5.0/gcc/gimple-expr.h index a50a90a959..20815b098b 100644 --- a/contrib/gcc-5.0/gcc/gimple-expr.h +++ b/contrib/gcc-5.0/gcc/gimple-expr.h @@ -36,8 +36,8 @@ extern tree create_tmp_reg (tree, const char * = NULL); extern tree create_tmp_reg_fn (struct function *, tree, const char *); -extern void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *, - tree *); +extern void extract_ops_from_tree (tree, enum tree_code *, tree *, tree *, + tree *); extern void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *, tree *); extern bool is_gimple_lvalue (tree); @@ -146,15 +146,15 @@ is_gimple_constant (const_tree t) } } -/* A wrapper around extract_ops_from_tree_1, for callers which expect - to see only a maximum of two operands. */ +/* A wrapper around extract_ops_from_tree with 3 ops, for callers which + expect to see only a maximum of two operands. */ static inline void extract_ops_from_tree (tree expr, enum tree_code *code, tree *op0, tree *op1) { tree op2; - extract_ops_from_tree_1 (expr, code, op0, op1, &op2); + extract_ops_from_tree (expr, code, op0, op1, &op2); gcc_assert (op2 == NULL_TREE); } diff --git a/contrib/gcc-5.0/gcc/gimple-fold.c b/contrib/gcc-5.0/gcc/gimple-fold.c index 78c50a9d0c..7950cb627f 100644 --- a/contrib/gcc-5.0/gcc/gimple-fold.c +++ b/contrib/gcc-5.0/gcc/gimple-fold.c @@ -948,21 +948,21 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, { tree src_base, dest_base, fn; HOST_WIDE_INT src_offset = 0, dest_offset = 0; - HOST_WIDE_INT size = -1; - HOST_WIDE_INT maxsize = -1; + HOST_WIDE_INT maxsize; srcvar = TREE_OPERAND (src, 0); - src_base = get_ref_base_and_extent (srcvar, &src_offset, - &size, &maxsize); + src_base = get_addr_base_and_unit_offset (srcvar, &src_offset); + if (src_base == NULL) + src_base = srcvar; destvar = TREE_OPERAND (dest, 0); - dest_base = get_ref_base_and_extent (destvar, &dest_offset, - &size, &maxsize); + dest_base = get_addr_base_and_unit_offset (destvar, + &dest_offset); + if (dest_base == NULL) + dest_base = destvar; if (tree_fits_uhwi_p (len)) maxsize = tree_to_uhwi (len); else maxsize = -1; - src_offset /= BITS_PER_UNIT; - dest_offset /= BITS_PER_UNIT; if (SSA_VAR_P (src_base) && SSA_VAR_P (dest_base)) { diff --git a/contrib/gcc-5.0/gcc/gimple-ssa-strength-reduction.c b/contrib/gcc-5.0/gcc/gimple-ssa-strength-reduction.c index 5b84bbecde..fef5905033 100644 --- a/contrib/gcc-5.0/gcc/gimple-ssa-strength-reduction.c +++ b/contrib/gcc-5.0/gcc/gimple-ssa-strength-reduction.c @@ -2267,7 +2267,7 @@ create_phi_basis (slsr_cand_t c, gimple from_phi, tree basis_name, slsr_cand_t basis = lookup_cand (c->basis); int nargs = gimple_phi_num_args (from_phi); basic_block phi_bb = gimple_bb (from_phi); - slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (from_phi)); + slsr_cand_t phi_cand = *stmt_cand_map->get (from_phi); phi_args.create (nargs); /* Process each argument of the existing phi that represents @@ -2376,7 +2376,7 @@ phi_add_costs (gimple phi, slsr_cand_t c, int one_add_cost) { unsigned i; int cost = 0; - slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi)); + slsr_cand_t phi_cand = *stmt_cand_map->get (phi); /* If we work our way back to a phi that isn't dominated by the hidden basis, this isn't a candidate for replacement. Indicate this by @@ -2587,7 +2587,7 @@ static void record_phi_increments (slsr_cand_t basis, gimple phi) { unsigned i; - slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi)); + slsr_cand_t phi_cand = *stmt_cand_map->get (phi); for (i = 0; i < gimple_phi_num_args (phi); i++) { @@ -2658,7 +2658,7 @@ phi_incr_cost (slsr_cand_t c, const widest_int &incr, gimple phi, int *savings) unsigned i; int cost = 0; slsr_cand_t basis = lookup_cand (c->basis); - slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi)); + slsr_cand_t phi_cand = *stmt_cand_map->get (phi); for (i = 0; i < gimple_phi_num_args (phi); i++) { @@ -3002,7 +3002,7 @@ ncd_with_phi (slsr_cand_t c, const widest_int &incr, gphi *phi, { unsigned i; slsr_cand_t basis = lookup_cand (c->basis); - slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi)); + slsr_cand_t phi_cand = *stmt_cand_map->get (phi); for (i = 0; i < gimple_phi_num_args (phi); i++) { @@ -3212,7 +3212,7 @@ all_phi_incrs_profitable (slsr_cand_t c, gimple phi) { unsigned i; slsr_cand_t basis = lookup_cand (c->basis); - slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi)); + slsr_cand_t phi_cand = *stmt_cand_map->get (phi); for (i = 0; i < gimple_phi_num_args (phi); i++) { diff --git a/contrib/gcc-5.0/gcc/gimple.c b/contrib/gcc-5.0/gcc/gimple.c index a5c1192f77..a0e542fa47 100644 --- a/contrib/gcc-5.0/gcc/gimple.c +++ b/contrib/gcc-5.0/gcc/gimple.c @@ -411,7 +411,7 @@ gimple_build_assign (tree lhs, tree rhs MEM_STAT_DECL) enum tree_code subcode; tree op1, op2, op3; - extract_ops_from_tree_1 (rhs, &subcode, &op1, &op2, &op3); + extract_ops_from_tree (rhs, &subcode, &op1, &op2, &op3); return gimple_build_assign (lhs, subcode, op1, op2, op3 PASS_MEM_STAT); } @@ -1595,7 +1595,7 @@ gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *gsi, tree expr) enum tree_code subcode; tree op1, op2, op3; - extract_ops_from_tree_1 (expr, &subcode, &op1, &op2, &op3); + extract_ops_from_tree (expr, &subcode, &op1, &op2, &op3); gimple_assign_set_rhs_with_ops (gsi, subcode, op1, op2, op3); } @@ -1953,6 +1953,11 @@ gimple_could_trap_p_1 (gimple s, bool include_mem, bool include_stores) && TYPE_OVERFLOW_TRAPS (t)), div)); + case GIMPLE_COND: + t = TREE_TYPE (gimple_cond_lhs (s)); + return operation_could_trap_p (gimple_cond_code (s), + FLOAT_TYPE_P (t), false, NULL_TREE); + default: break; } diff --git a/contrib/gcc-5.0/gcc/gimplify.c b/contrib/gcc-5.0/gcc/gimplify.c index c85f83a5bc..46528ec8bf 100644 --- a/contrib/gcc-5.0/gcc/gimplify.c +++ b/contrib/gcc-5.0/gcc/gimplify.c @@ -4095,7 +4095,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, } /* Vector types use CONSTRUCTOR all the way through gimple - compilation as a general initializer. */ + compilation as a general initializer. */ FOR_EACH_VEC_SAFE_ELT (elts, ix, ce) { enum gimplify_status tret; @@ -4103,6 +4103,10 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, fb_rvalue); if (tret == GS_ERROR) ret = GS_ERROR; + else if (TREE_STATIC (ctor) + && !initializer_constant_valid_p (ce->value, + TREE_TYPE (ce->value))) + TREE_STATIC (ctor) = 0; } if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0))) TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p); @@ -5208,12 +5212,38 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) TREE_VALUE (link) = error_mark_node; tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, is_gimple_lvalue, fb_lvalue | fb_mayfail); + if (tret != GS_ERROR) + { + /* Unlike output operands, memory inputs are not guaranteed + to be lvalues by the FE, and while the expressions are + marked addressable there, if it is e.g. a statement + expression, temporaries in it might not end up being + addressable. They might be already used in the IL and thus + it is too late to make them addressable now though. */ + tree x = TREE_VALUE (link); + while (handled_component_p (x)) + x = TREE_OPERAND (x, 0); + if (TREE_CODE (x) == MEM_REF + && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR) + x = TREE_OPERAND (TREE_OPERAND (x, 0), 0); + if ((TREE_CODE (x) == VAR_DECL + || TREE_CODE (x) == PARM_DECL + || TREE_CODE (x) == RESULT_DECL) + && !TREE_ADDRESSABLE (x) + && is_gimple_reg (x)) + { + warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), + input_location), 0, + "memory input %d is not directly addressable", + i); + prepare_gimple_addressable (&TREE_VALUE (link), pre_p); + } + } mark_addressable (TREE_VALUE (link)); if (tret == GS_ERROR) { - if (EXPR_HAS_LOCATION (TREE_VALUE (link))) - input_location = EXPR_LOCATION (TREE_VALUE (link)); - error ("memory input %d is not directly addressable", i); + error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location), + "memory input %d is not directly addressable", i); ret = tret; } } diff --git a/contrib/gcc-5.0/gcc/haifa-sched.c b/contrib/gcc-5.0/gcc/haifa-sched.c index ad2450b7da..61bfe941a3 100644 --- a/contrib/gcc-5.0/gcc/haifa-sched.c +++ b/contrib/gcc-5.0/gcc/haifa-sched.c @@ -5691,7 +5691,10 @@ autopref_multipass_dfa_lookahead_guard (rtx_insn *insn1, int ready_index) { int r = 0; - if (PARAM_VALUE (PARAM_SCHED_AUTOPREF_QUEUE_DEPTH) <= 0) + /* Exit early if the param forbids this or if we're not entering here through + normal haifa scheduling. This can happen if selective scheduling is + explicitly enabled. */ + if (!insn_queue || PARAM_VALUE (PARAM_SCHED_AUTOPREF_QUEUE_DEPTH) <= 0) return 0; if (sched_verbose >= 2 && ready_index == 0) @@ -7369,6 +7372,7 @@ haifa_sched_finish (void) sched_deps_finish (); sched_finish_luids (); current_sched_info = NULL; + insn_queue = NULL; sched_finish (); } diff --git a/contrib/gcc-5.0/gcc/ifcvt.c b/contrib/gcc-5.0/gcc/ifcvt.c index db07889a0f..e26b2c832c 100644 --- a/contrib/gcc-5.0/gcc/ifcvt.c +++ b/contrib/gcc-5.0/gcc/ifcvt.c @@ -2152,45 +2152,22 @@ noce_try_abs (struct noce_if_info *if_info) Note that these rtx constants are known to be CONST_INT, and therefore imply integer comparisons. The one_cmpl case is more complicated, as we want to handle - only x < 0 ? ~x : x or x >= 0 ? ~x : x but not - x <= 0 ? ~x : x or x > 0 ? ~x : x, as the latter two - have different result for x == 0. */ + only x < 0 ? ~x : x or x >= 0 ? x : ~x to one_cmpl_abs (x) + and x < 0 ? x : ~x or x >= 0 ? ~x : x to ~one_cmpl_abs (x), + but not other cases (x > -1 is equivalent of x >= 0). */ if (c == constm1_rtx && GET_CODE (cond) == GT) - { - if (one_cmpl && negate) - return FALSE; - } + ; else if (c == const1_rtx && GET_CODE (cond) == LT) { - if (one_cmpl && !negate) + if (one_cmpl) return FALSE; } else if (c == CONST0_RTX (GET_MODE (b))) { - if (one_cmpl) - switch (GET_CODE (cond)) - { - case GT: - if (!negate) - return FALSE; - break; - case GE: - /* >= 0 is the same case as above > -1. */ - if (negate) - return FALSE; - break; - case LT: - if (negate) - return FALSE; - break; - case LE: - /* <= 0 is the same case as above < 1. */ - if (!negate) - return FALSE; - break; - default: - return FALSE; - } + if (one_cmpl + && GET_CODE (cond) != GE + && GET_CODE (cond) != LT) + return FALSE; } else return FALSE; @@ -3847,8 +3824,11 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) return FALSE; /* If the conditional jump is more than just a conditional jump, then - we can not do if-conversion on this block. */ - if (! onlyjump_p (jump)) + we can not do if-conversion on this block. Give up for returnjump_p, + changing a conditional return followed by unconditional trap for + conditional trap followed by unconditional return is likely not + beneficial and harder to handle. */ + if (! onlyjump_p (jump) || returnjump_p (jump)) return FALSE; /* We must be comparing objects whose modes imply the size. */ diff --git a/contrib/gcc-5.0/gcc/ipa-cp.c b/contrib/gcc-5.0/gcc/ipa-cp.c index bfe4821da3..81a6ef8e06 100644 --- a/contrib/gcc-5.0/gcc/ipa-cp.c +++ b/contrib/gcc-5.0/gcc/ipa-cp.c @@ -1787,6 +1787,18 @@ propagate_aggs_accross_jump_function (struct cgraph_edge *cs, return ret; } +/* Return true if on the way cfrom CS->caller to the final (non-alias and + non-thunk) destination, the call passes through a thunk. */ + +static bool +call_passes_through_thunk_p (cgraph_edge *cs) +{ + cgraph_node *alias_or_thunk = cs->callee; + while (alias_or_thunk->alias) + alias_or_thunk = alias_or_thunk->get_alias_target (); + return alias_or_thunk->thunk.thunk_p; +} + /* Propagate constants from the caller to the callee of CS. INFO describes the caller. */ @@ -1795,7 +1807,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs) { struct ipa_node_params *callee_info; enum availability availability; - struct cgraph_node *callee, *alias_or_thunk; + cgraph_node *callee; struct ipa_edge_args *args; bool ret = false; int i, args_count, parms_count; @@ -1833,10 +1845,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs) /* If this call goes through a thunk we must not propagate to the first (0th) parameter. However, we might need to uncover a thunk from below a series of aliases first. */ - alias_or_thunk = cs->callee; - while (alias_or_thunk->alias) - alias_or_thunk = alias_or_thunk->get_alias_target (); - if (alias_or_thunk->thunk.thunk_p) + if (call_passes_through_thunk_p (cs)) { ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, 0)); @@ -3404,7 +3413,11 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node, struct ipa_jump_func *jump_func; tree t; - if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))) + if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) + || (i == 0 + && call_passes_through_thunk_p (cs)) + || (!cs->callee->instrumentation_clone + && cs->callee->function_symbol ()->instrumentation_clone)) { newval = NULL_TREE; break; diff --git a/contrib/gcc-5.0/gcc/ipa-devirt.c b/contrib/gcc-5.0/gcc/ipa-devirt.c index e3197855f3..c165bceb16 100644 --- a/contrib/gcc-5.0/gcc/ipa-devirt.c +++ b/contrib/gcc-5.0/gcc/ipa-devirt.c @@ -1536,6 +1536,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, break; } case VOID_TYPE: + case NULLPTR_TYPE: break; default: diff --git a/contrib/gcc-5.0/gcc/ipa-icf.c b/contrib/gcc-5.0/gcc/ipa-icf.c index 3f29011752..729bc06815 100644 --- a/contrib/gcc-5.0/gcc/ipa-icf.c +++ b/contrib/gcc-5.0/gcc/ipa-icf.c @@ -444,7 +444,7 @@ bool sem_function::param_used_p (unsigned int i) { if (ipa_node_params_sum == NULL) - return false; + return true; struct ipa_node_params *parms_info = IPA_NODE_REF (get_node ()); @@ -1528,6 +1528,11 @@ sem_function::parse (cgraph_node *node, bitmap_obstack *stack) if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL) return NULL; + /* PR ipa/70306. */ + if (DECL_STATIC_CONSTRUCTOR (node->decl) + || DECL_STATIC_DESTRUCTOR (node->decl)) + return NULL; + sem_function *f = new sem_function (node, 0, stack); f->init (); diff --git a/contrib/gcc-5.0/gcc/ipa-inline-analysis.c b/contrib/gcc-5.0/gcc/ipa-inline-analysis.c index 54b6abeb34..ff40b2b4e7 100644 --- a/contrib/gcc-5.0/gcc/ipa-inline-analysis.c +++ b/contrib/gcc-5.0/gcc/ipa-inline-analysis.c @@ -249,13 +249,14 @@ struct agg_position_info bool by_ref; }; -/* Add condition to condition list CONDS. AGGPOS describes whether the used - oprand is loaded from an aggregate and where in the aggregate it is. It can - be NULL, which means this not a load from an aggregate. */ +/* Add condition to condition list SUMMARY. OPERAND_NUM, SIZE, CODE and VAL + correspond to fields of condition structure. AGGPOS describes whether the + used operand is loaded from an aggregate and where in the aggregate it is. + It can be NULL, which means this not a load from an aggregate. */ static struct predicate add_condition (struct inline_summary *summary, int operand_num, - struct agg_position_info *aggpos, + HOST_WIDE_INT size, struct agg_position_info *aggpos, enum tree_code code, tree val) { int i; @@ -281,6 +282,7 @@ add_condition (struct inline_summary *summary, int operand_num, for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++) { if (c->operand_num == operand_num + && c->size == size && c->code == code && c->val == val && c->agg_contents == agg_contents @@ -297,6 +299,7 @@ add_condition (struct inline_summary *summary, int operand_num, new_cond.agg_contents = agg_contents; new_cond.by_ref = by_ref; new_cond.offset = offset; + new_cond.size = size; vec_safe_push (summary->conds, new_cond); return single_cond_predicate (i + predicate_first_dynamic_condition); } @@ -900,21 +903,25 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, clause |= 1 << (i + predicate_first_dynamic_condition); continue; } - if (c->code == IS_NOT_CONSTANT || c->code == CHANGED) + if (c->code == CHANGED) continue; - if (operand_equal_p (TYPE_SIZE (TREE_TYPE (c->val)), - TYPE_SIZE (TREE_TYPE (val)), 0)) + if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size) { - val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val); + clause |= 1 << (i + predicate_first_dynamic_condition); + continue; + } + if (c->code == IS_NOT_CONSTANT) + continue; - res = val - ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val) - : NULL; + val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val); + res = val + ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val) + : NULL; + + if (res && integer_zerop (res)) + continue; - if (res && integer_zerop (res)) - continue; - } clause |= 1 << (i + predicate_first_dynamic_condition); } return clause; @@ -1551,16 +1558,21 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED, } /* If OP refers to value of function parameter, return the corresponding - parameter. */ + parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the + PARM_DECL) will be stored to *SIZE_P in that case too. */ static tree -unmodified_parm_1 (gimple stmt, tree op) +unmodified_parm_1 (gimple stmt, tree op, HOST_WIDE_INT *size_p) { /* SSA_NAME referring to parm default def? */ if (TREE_CODE (op) == SSA_NAME && SSA_NAME_IS_DEFAULT_DEF (op) && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL) - return SSA_NAME_VAR (op); + { + if (size_p) + *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op))); + return SSA_NAME_VAR (op); + } /* Non-SSA parm reference? */ if (TREE_CODE (op) == PARM_DECL) { @@ -1571,18 +1583,24 @@ unmodified_parm_1 (gimple stmt, tree op) walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified, NULL); if (!modified) - return op; + { + if (size_p) + *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op))); + return op; + } } return NULL_TREE; } /* If OP refers to value of function parameter, return the corresponding - parameter. Also traverse chains of SSA register assignments. */ + parameter. Also traverse chains of SSA register assignments. If non-NULL, + the size of the memory load (or the SSA_NAME of the PARM_DECL) will be + stored to *SIZE_P in that case too. */ static tree -unmodified_parm (gimple stmt, tree op) +unmodified_parm (gimple stmt, tree op, HOST_WIDE_INT *size_p) { - tree res = unmodified_parm_1 (stmt, op); + tree res = unmodified_parm_1 (stmt, op, size_p); if (res) return res; @@ -1590,23 +1608,25 @@ unmodified_parm (gimple stmt, tree op) && !SSA_NAME_IS_DEFAULT_DEF (op) && gimple_assign_single_p (SSA_NAME_DEF_STMT (op))) return unmodified_parm (SSA_NAME_DEF_STMT (op), - gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op))); + gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)), + size_p); return NULL_TREE; } /* If OP refers to a value of a function parameter or value loaded from an aggregate passed to a parameter (either by value or reference), return TRUE - and store the number of the parameter to *INDEX_P and information whether - and how it has been loaded from an aggregate into *AGGPOS. INFO describes - the function parameters, STMT is the statement in which OP is used or - loaded. */ + and store the number of the parameter to *INDEX_P, the access size into + *SIZE_P, and information whether and how it has been loaded from an + aggregate into *AGGPOS. INFO describes the function parameters, STMT is the + statement in which OP is used or loaded. */ static bool unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi, gimple stmt, tree op, int *index_p, + HOST_WIDE_INT *size_p, struct agg_position_info *aggpos) { - tree res = unmodified_parm_1 (stmt, op); + tree res = unmodified_parm_1 (stmt, op, size_p); gcc_checking_assert (aggpos); if (res) @@ -1627,14 +1647,14 @@ unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi, stmt = SSA_NAME_DEF_STMT (op); op = gimple_assign_rhs1 (stmt); if (!REFERENCE_CLASS_P (op)) - return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, + return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p, aggpos); } aggpos->agg_contents = true; return ipa_load_from_parm_agg (fbi, fbi->info->descriptors, stmt, op, index_p, &aggpos->offset, - NULL, &aggpos->by_ref); + size_p, &aggpos->by_ref); } /* See if statement might disappear after inlining. @@ -1685,7 +1705,7 @@ eliminated_by_inlining_prob (gimple stmt) inner_lhs = lhs; /* Reads of parameter are expected to be free. */ - if (unmodified_parm (stmt, inner_rhs)) + if (unmodified_parm (stmt, inner_rhs, NULL)) rhs_free = true; /* Match expressions of form &this->field. Those will most likely combine with something upstream after inlining. */ @@ -1695,7 +1715,7 @@ eliminated_by_inlining_prob (gimple stmt) if (TREE_CODE (op) == PARM_DECL) rhs_free = true; else if (TREE_CODE (op) == MEM_REF - && unmodified_parm (stmt, TREE_OPERAND (op, 0))) + && unmodified_parm (stmt, TREE_OPERAND (op, 0), NULL)) rhs_free = true; } @@ -1708,7 +1728,7 @@ eliminated_by_inlining_prob (gimple stmt) /* Reads of parameters passed by reference expected to be free (i.e. optimized out after inlining). */ if (TREE_CODE (inner_rhs) == MEM_REF - && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0))) + && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0), NULL)) rhs_free = true; /* Copying parameter passed by reference into gimple register is @@ -1749,7 +1769,7 @@ eliminated_by_inlining_prob (gimple stmt) if (TREE_CODE (inner_lhs) == PARM_DECL || TREE_CODE (inner_lhs) == RESULT_DECL || (TREE_CODE (inner_lhs) == MEM_REF - && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0)) + && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0), NULL) || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0)) && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND @@ -1779,6 +1799,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, { gimple last; tree op; + HOST_WIDE_INT size; int index; struct agg_position_info aggpos; enum tree_code code, inverted_code; @@ -1796,7 +1817,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, /* TODO: handle conditionals like var = op0 < 4; if (var != 0). */ - if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos)) + if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos)) { code = gimple_cond_code (last); inverted_code = invert_tree_comparison (code, HONOR_NANS (op)); @@ -1810,7 +1831,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, unordered one. Be sure it is not confused with NON_CONSTANT. */ if (this_code != ERROR_MARK) { - struct predicate p = add_condition (summary, index, &aggpos, + struct predicate p = add_condition (summary, index, size, &aggpos, this_code, gimple_cond_rhs (last)); e->aux = pool_alloc (edge_predicate_pool); @@ -1839,11 +1860,12 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, || gimple_call_num_args (set_stmt) != 1) return; op2 = gimple_call_arg (set_stmt, 0); - if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &aggpos)) + if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &size, + &aggpos)) return; FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE) { - struct predicate p = add_condition (summary, index, &aggpos, + struct predicate p = add_condition (summary, index, size, &aggpos, IS_NOT_CONSTANT, NULL_TREE); e->aux = pool_alloc (edge_predicate_pool); *(struct predicate *) e->aux = p; @@ -1862,6 +1884,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, gimple lastg; tree op; int index; + HOST_WIDE_INT size; struct agg_position_info aggpos; edge e; edge_iterator ei; @@ -1873,7 +1896,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, return; gswitch *last = as_a (lastg); op = gimple_switch_index (last); - if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos)) + if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos)) return; FOR_EACH_EDGE (e, ei, bb->succs) @@ -1898,12 +1921,12 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, if (!min && !max) p = true_predicate (); else if (!max) - p = add_condition (summary, index, &aggpos, EQ_EXPR, min); + p = add_condition (summary, index, size, &aggpos, EQ_EXPR, min); else { struct predicate p1, p2; - p1 = add_condition (summary, index, &aggpos, GE_EXPR, min); - p2 = add_condition (summary, index, &aggpos, LE_EXPR, max); + p1 = add_condition (summary, index, size, &aggpos, GE_EXPR, min); + p2 = add_condition (summary, index, size, &aggpos, LE_EXPR, max); p = and_predicates (summary->conds, &p1, &p2); } *(struct predicate *) e->aux @@ -2003,13 +2026,14 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info, { tree parm; int index; + HOST_WIDE_INT size; while (UNARY_CLASS_P (expr)) expr = TREE_OPERAND (expr, 0); - parm = unmodified_parm (NULL, expr); + parm = unmodified_parm (NULL, expr, &size); if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0) - return add_condition (summary, index, NULL, CHANGED, NULL_TREE); + return add_condition (summary, index, size, NULL, CHANGED, NULL_TREE); if (is_gimple_min_invariant (expr)) return false_predicate (); if (TREE_CODE (expr) == SSA_NAME) @@ -2070,6 +2094,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, struct predicate op_non_const; bool is_load; int base_index; + HOST_WIDE_INT size; struct agg_position_info aggpos; /* What statments might be optimized away @@ -2093,7 +2118,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, tree op; gcc_assert (gimple_assign_single_p (stmt)); op = gimple_assign_rhs1 (stmt); - if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, + if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, &size, &aggpos)) return p; } @@ -2104,7 +2129,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, adding conditionals. */ FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) { - tree parm = unmodified_parm (stmt, use); + tree parm = unmodified_parm (stmt, use, NULL); /* For arguments we can build a condition. */ if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0) continue; @@ -2119,18 +2144,19 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, if (is_load) op_non_const = - add_condition (summary, base_index, &aggpos, CHANGED, NULL); + add_condition (summary, base_index, size, &aggpos, CHANGED, NULL); else op_non_const = false_predicate (); FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) { - tree parm = unmodified_parm (stmt, use); + HOST_WIDE_INT size; + tree parm = unmodified_parm (stmt, use, &size); int index; if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0) { if (index != base_index) - p = add_condition (summary, index, NULL, CHANGED, NULL_TREE); + p = add_condition (summary, index, size, NULL, CHANGED, NULL_TREE); else continue; } @@ -3384,7 +3410,8 @@ remap_predicate (struct inline_summary *info, ap.by_ref = c->by_ref; cond_predicate = add_condition (info, operand_map[c->operand_num], - &ap, c->code, c->val); + c->size, &ap, c->code, + c->val); } } /* Fixed conditions remains same, construct single @@ -4239,6 +4266,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data, { struct condition c; c.operand_num = streamer_read_uhwi (&ib); + c.size = streamer_read_uhwi (&ib); c.code = (enum tree_code) streamer_read_uhwi (&ib); c.val = stream_read_tree (&ib, data_in); bp = streamer_read_bitpack (&ib); @@ -4403,6 +4431,7 @@ inline_write_summary (void) for (i = 0; vec_safe_iterate (info->conds, i, &c); i++) { streamer_write_uhwi (ob, c->operand_num); + streamer_write_uhwi (ob, c->size); streamer_write_uhwi (ob, c->code); stream_write_tree (ob, c->val, true); bp = bitpack_create (ob->main_stream); diff --git a/contrib/gcc-5.0/gcc/ipa-inline.h b/contrib/gcc-5.0/gcc/ipa-inline.h index 85041f67dd..5a2599d54f 100644 --- a/contrib/gcc-5.0/gcc/ipa-inline.h +++ b/contrib/gcc-5.0/gcc/ipa-inline.h @@ -34,6 +34,8 @@ struct GTY(()) condition /* If agg_contents is set, this is the offset from which the used data was loaded. */ HOST_WIDE_INT offset; + /* Size of the access reading the data (or the PARM_DECL SSA_NAME). */ + HOST_WIDE_INT size; tree val; int operand_num; ENUM_BITFIELD(tree_code) code : 16; diff --git a/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c b/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c index 17e0a46130..9fd302e03d 100644 --- a/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c +++ b/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c @@ -528,7 +528,7 @@ contains_type_p (tree outer_type, HOST_WIDE_INT offset, tree inlined_polymorphic_ctor_dtor_block_p (tree block, bool check_clones) { - tree fn = BLOCK_ABSTRACT_ORIGIN (block); + tree fn = block_ultimate_origin (block); if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL) return NULL_TREE; @@ -1184,7 +1184,7 @@ noncall_stmt_may_be_vtbl_ptr_store (gimple stmt) for (tree block = gimple_block (stmt); block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block)) if (BLOCK_ABSTRACT_ORIGIN (block) - && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) == FUNCTION_DECL) + && TREE_CODE (block_ultimate_origin (block)) == FUNCTION_DECL) return inlined_polymorphic_ctor_dtor_block_p (block, false); return (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE && (DECL_CXX_CONSTRUCTOR_P (current_function_decl) diff --git a/contrib/gcc-5.0/gcc/ipa-prop.c b/contrib/gcc-5.0/gcc/ipa-prop.c index 9298fac9d5..a7515f1791 100644 --- a/contrib/gcc-5.0/gcc/ipa-prop.c +++ b/contrib/gcc-5.0/gcc/ipa-prop.c @@ -1461,6 +1461,9 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg, bool check_ref, by_ref; ao_ref r; + if (PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS) == 0) + return; + /* The function operates in three stages. First, we prepare check_ref, r, arg_base and arg_offset based on what is actually passed as an actual argument. */ @@ -1683,7 +1686,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, unsigned HOST_WIDE_INT hwi_bitpos; unsigned align; - if (get_pointer_alignment_1 (arg, &align, &hwi_bitpos) + get_pointer_alignment_1 (arg, &align, &hwi_bitpos); + if (align > BITS_PER_UNIT && align % BITS_PER_UNIT == 0 && hwi_bitpos % BITS_PER_UNIT == 0) { diff --git a/contrib/gcc-5.0/gcc/ipa-pure-const.c b/contrib/gcc-5.0/gcc/ipa-pure-const.c index a4cdae9508..8bfc649e14 100644 --- a/contrib/gcc-5.0/gcc/ipa-pure-const.c +++ b/contrib/gcc-5.0/gcc/ipa-pure-const.c @@ -1961,10 +1961,25 @@ pass_nothrow::execute (function *) } node->set_nothrow_flag (true); + + bool cfg_changed = false; + if (self_recursive_p (node)) + FOR_EACH_BB_FN (this_block, cfun) + if (gimple g = last_stmt (this_block)) + if (is_gimple_call (g)) + { + tree callee_t = gimple_call_fndecl (g); + if (callee_t + && recursive_call_p (current_function_decl, callee_t) + && maybe_clean_eh_stmt (g) + && gimple_purge_dead_eh_edges (this_block)) + cfg_changed = true; + } + if (dump_file) fprintf (dump_file, "Function found to be nothrow: %s\n", current_function_name ()); - return 0; + return cfg_changed ? TODO_cleanup_cfg : 0; } } // anon namespace diff --git a/contrib/gcc-5.0/gcc/ipa-split.c b/contrib/gcc-5.0/gcc/ipa-split.c index 5d6763d102..b9678e11db 100644 --- a/contrib/gcc-5.0/gcc/ipa-split.c +++ b/contrib/gcc-5.0/gcc/ipa-split.c @@ -1306,8 +1306,8 @@ split_function (basic_block return_bb, struct split_point *split_point, FIXME: Once we are able to change return type, we should change function to return void instead of just outputting function with undefined return value. For structures this affects quality of codegen. */ - else if (!split_point->split_part_set_retval - && find_retval (return_bb)) + else if ((retval = find_retval (return_bb)) + && !split_point->split_part_set_retval) { bool redirected = true; basic_block new_return_bb = create_basic_block (NULL, 0, return_bb); @@ -1402,6 +1402,44 @@ split_function (basic_block return_bb, struct split_point *split_point, DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; } + /* If return_bb contains any clobbers that refer to SSA_NAMEs + set in the split part, remove them. Also reset debug stmts that + refer to SSA_NAMEs set in the split part. */ + if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) + { + gimple_stmt_iterator gsi = gsi_start_bb (return_bb); + while (!gsi_end_p (gsi)) + { + tree op; + ssa_op_iter iter; + gimple stmt = gsi_stmt (gsi); + bool remove = false; + if (gimple_clobber_p (stmt) || is_gimple_debug (stmt)) + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) + { + basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (op)); + if (op != retval + && bb + && bb != return_bb + && bitmap_bit_p (split_point->split_bbs, bb->index)) + { + if (is_gimple_debug (stmt)) + { + gimple_debug_bind_reset_value (stmt); + update_stmt (stmt); + } + else + remove = true; + break; + } + } + if (remove) + gsi_remove (&gsi, true); + else + gsi_next (&gsi); + } + } + /* If the original function is instrumented then it's part is also instrumented. */ if (with_bounds) @@ -1554,7 +1592,7 @@ split_function (basic_block return_bb, struct split_point *split_point, return value into and put call just before it. */ if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) { - real_retval = retval = find_retval (return_bb); + real_retval = retval; retbnd = find_retbnd (return_bb); if (real_retval && split_point->split_part_set_retval) @@ -1600,6 +1638,28 @@ split_function (basic_block return_bb, struct split_point *split_point, break; } update_stmt (gsi_stmt (bsi)); + /* Also adjust clobbers and debug stmts in return_bb. */ + for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi); + gsi_next (&bsi)) + { + gimple stmt = gsi_stmt (bsi); + if (gimple_clobber_p (stmt) + || is_gimple_debug (stmt)) + { + ssa_op_iter iter; + use_operand_p use_p; + bool update = false; + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, + SSA_OP_USE) + if (USE_FROM_PTR (use_p) == real_retval) + { + SET_USE (use_p, retval); + update = true; + } + if (update) + update_stmt (stmt); + } + } } /* Replace retbnd with new one. */ diff --git a/contrib/gcc-5.0/gcc/ira-build.c b/contrib/gcc-5.0/gcc/ira-build.c index 189f340800..c278da4281 100644 --- a/contrib/gcc-5.0/gcc/ira-build.c +++ b/contrib/gcc-5.0/gcc/ira-build.c @@ -2291,7 +2291,7 @@ mark_loops_for_removal (void) ); } qsort (sorted_loops, n, sizeof (ira_loop_tree_node_t), loop_compare_func); - for (i = 0; n - i + 1 > IRA_MAX_LOOPS_NUM; i++) + for (i = 0; i < n - IRA_MAX_LOOPS_NUM; i++) { sorted_loops[i]->to_remove_p = true; if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL) diff --git a/contrib/gcc-5.0/gcc/ira.c b/contrib/gcc-5.0/gcc/ira.c index e63b0fa210..cbc5bd0fe2 100644 --- a/contrib/gcc-5.0/gcc/ira.c +++ b/contrib/gcc-5.0/gcc/ira.c @@ -3349,9 +3349,6 @@ adjust_cleared_regs (rtx loc, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data) return NULL_RTX; } -/* Nonzero if we recorded an equivalence for a LABEL_REF. */ -static int recorded_label_ref; - /* Find registers that are equivalent to a single value throughout the compilation (either because they can be referenced in memory or are set once from a single constant). Lower their priority for a @@ -3361,10 +3358,8 @@ static int recorded_label_ref; value into the using insn. If it succeeds, we can eliminate the register completely. - Initialize init_insns in ira_reg_equiv array. - - Return non-zero if jump label rebuilding should be done. */ -static int + Initialize init_insns in ira_reg_equiv array. */ +static void update_equiv_regs (void) { rtx_insn *insn; @@ -3373,10 +3368,6 @@ update_equiv_regs (void) bitmap cleared_regs; bool *pdx_subregs; - /* We need to keep track of whether or not we recorded a LABEL_REF so - that we know if the jump optimizer needs to be rerun. */ - recorded_label_ref = 0; - /* Use pdx_subregs to show whether a reg is used in a paradoxical subreg. */ pdx_subregs = XCNEWVEC (bool, max_regno); @@ -3422,7 +3413,8 @@ update_equiv_regs (void) /* If this insn contains more (or less) than a single SET, only mark all destinations as having no known equivalence. */ - if (set == NULL_RTX) + if (set == NULL_RTX + || side_effects_p (SET_SRC (set))) { note_stores (PATTERN (insn), no_equiv, NULL); continue; @@ -3607,17 +3599,6 @@ update_equiv_regs (void) = gen_rtx_INSN_LIST (VOIDmode, insn, ira_reg_equiv[regno].init_insns); - /* Record whether or not we created a REG_EQUIV note for a LABEL_REF. - We might end up substituting the LABEL_REF for uses of the - pseudo here or later. That kind of transformation may turn an - indirect jump into a direct jump, in which case we must rerun the - jump optimizer to ensure that the JUMP_LABEL fields are valid. */ - if (GET_CODE (x) == LABEL_REF - || (GET_CODE (x) == CONST - && GET_CODE (XEXP (x, 0)) == PLUS - && (GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF))) - recorded_label_ref = 1; - reg_equiv[regno].replacement = x; reg_equiv[regno].src_p = &SET_SRC (set); reg_equiv[regno].loop_depth = (short) loop_depth; @@ -3735,9 +3716,9 @@ update_equiv_regs (void) if (! INSN_P (insn)) continue; - /* Don't substitute into a non-local goto, this confuses CFG. */ - if (JUMP_P (insn) - && find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) + /* Don't substitute into jumps. indirect_jump_optimize does + this for anything we are prepared to handle. */ + if (JUMP_P (insn)) continue; for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) @@ -3889,11 +3870,60 @@ update_equiv_regs (void) end_alias_analysis (); free (reg_equiv); free (pdx_subregs); - return recorded_label_ref; } - +/* A pass over indirect jumps, converting simple cases to direct jumps. + Combine does this optimization too, but only within a basic block. */ +static void +indirect_jump_optimize (void) +{ + basic_block bb; + bool rebuild_p = false; + + FOR_EACH_BB_REVERSE_FN (bb, cfun) + { + rtx_insn *insn = BB_END (bb); + if (!JUMP_P (insn) + || find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) + continue; + + rtx x = pc_set (insn); + if (!x || !REG_P (SET_SRC (x))) + continue; + + int regno = REGNO (SET_SRC (x)); + if (DF_REG_DEF_COUNT (regno) == 1) + { + df_ref def = DF_REG_DEF_CHAIN (regno); + if (!DF_REF_IS_ARTIFICIAL (def)) + { + rtx_insn *def_insn = DF_REF_INSN (def); + rtx lab = NULL_RTX; + rtx set = single_set (def_insn); + if (set && GET_CODE (SET_SRC (set)) == LABEL_REF) + lab = SET_SRC (set); + else + { + rtx eqnote = find_reg_note (def_insn, REG_EQUAL, NULL_RTX); + if (eqnote && GET_CODE (XEXP (eqnote, 0)) == LABEL_REF) + lab = XEXP (eqnote, 0); + } + if (lab && validate_replace_rtx (SET_SRC (x), lab, insn)) + rebuild_p = true; + } + } + } + if (rebuild_p) + { + timevar_push (TV_JUMP); + rebuild_jump_labels (get_insns ()); + if (purge_all_dead_edges ()) + delete_unreachable_blocks (); + timevar_pop (TV_JUMP); + } +} + /* Set up fields memory, constant, and invariant from init_insns in the structures of array ira_reg_equiv. */ static void @@ -5123,7 +5153,6 @@ ira (FILE *f) { bool loops_p; int ira_max_point_before_emit; - int rebuild_p; bool saved_flag_caller_saves = flag_caller_saves; enum ira_region saved_flag_ira_region = flag_ira_region; @@ -5200,6 +5229,10 @@ ira (FILE *f) df_clear_flags (DF_NO_INSN_RESCAN); + indirect_jump_optimize (); + if (delete_trivially_dead_insns (get_insns (), max_reg_num ())) + df_analyze (); + regstat_init_n_sets_and_refs (); regstat_compute_ri (); @@ -5217,24 +5250,12 @@ ira (FILE *f) if (resize_reg_info () && flag_ira_loop_pressure) ira_set_pseudo_classes (true, ira_dump_file); - rebuild_p = update_equiv_regs (); + update_equiv_regs (); setup_reg_equiv (); setup_reg_equiv_init (); - if (optimize && rebuild_p) - { - timevar_push (TV_JUMP); - rebuild_jump_labels (get_insns ()); - if (purge_all_dead_edges ()) - delete_unreachable_blocks (); - timevar_pop (TV_JUMP); - } - allocated_reg_info_size = max_reg_num (); - if (delete_trivially_dead_insns (get_insns (), max_reg_num ())) - df_analyze (); - /* It is not worth to do such improvement when we use a simple allocation because of -O0 usage or because the function is too big. */ diff --git a/contrib/gcc-5.0/gcc/lra-constraints.c b/contrib/gcc-5.0/gcc/lra-constraints.c index c79a51565e..f4cf6fbc84 100644 --- a/contrib/gcc-5.0/gcc/lra-constraints.c +++ b/contrib/gcc-5.0/gcc/lra-constraints.c @@ -5163,8 +5163,10 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail) curr_id = lra_get_insn_recog_data (curr_insn); curr_static_id = curr_id->insn_static_data; remove_p = false; - if ((set = single_set (curr_insn)) != NULL_RTX && REG_P (SET_DEST (set)) + if ((set = single_set (curr_insn)) != NULL_RTX + && REG_P (SET_DEST (set)) && (regno = REGNO (SET_DEST (set))) >= FIRST_PSEUDO_REGISTER + && SET_DEST (set) != pic_offset_table_rtx && bitmap_bit_p (&check_only_regs, regno) && ! bitmap_bit_p (&live_regs, regno)) remove_p = true; @@ -5802,6 +5804,24 @@ get_regno (rtx reg) return -1; } +/* Delete a move INSN with destination reg DREGNO and a previous + clobber insn with the same regno. The inheritance/split code can + generate moves with preceding clobber and when we delete such moves + we should delete the clobber insn too to keep the correct life + info. */ +static void +delete_move_and_clobber (rtx_insn *insn, int dregno) +{ + rtx_insn *prev_insn = PREV_INSN (insn); + + lra_set_insn_deleted (insn); + lra_assert (dregno > 0); + if (prev_insn != NULL && NONDEBUG_INSN_P (prev_insn) + && GET_CODE (PATTERN (prev_insn)) == CLOBBER + && dregno == get_regno (XEXP (PATTERN (prev_insn), 0))) + lra_set_insn_deleted (prev_insn); +} + /* Remove inheritance/split pseudos which are in REMOVE_PSEUDOS and return true if we did any change. The undo transformations for inheritance looks like @@ -5874,7 +5894,7 @@ remove_inheritance_pseudos (bitmap remove_pseudos) ? "split" : "inheritance"); dump_insn_slim (lra_dump_file, curr_insn); } - lra_set_insn_deleted (curr_insn); + delete_move_and_clobber (curr_insn, dregno); done_p = true; } else if (bitmap_bit_p (remove_pseudos, sregno) @@ -6074,7 +6094,7 @@ undo_optional_reloads (void) INSN_UID (insn)); dump_insn_slim (lra_dump_file, insn); } - lra_set_insn_deleted (insn); + delete_move_and_clobber (insn, REGNO (dest)); continue; } /* We should not worry about generation memory-memory diff --git a/contrib/gcc-5.0/gcc/lra-remat.c b/contrib/gcc-5.0/gcc/lra-remat.c index f2d226c6fc..5e5d62c50b 100644 --- a/contrib/gcc-5.0/gcc/lra-remat.c +++ b/contrib/gcc-5.0/gcc/lra-remat.c @@ -112,6 +112,9 @@ static int call_used_regs_arr[FIRST_PSEUDO_REGISTER]; /* Bitmap used for different calculations. */ static bitmap_head temp_bitmap; +/* Registers accessed via subreg_p. */ +static bitmap_head subreg_regs; + typedef struct cand *cand_t; typedef const struct cand *const_cand_t; @@ -144,6 +147,10 @@ static vec all_cands; /* Map: insn -> candidate representing it. It is null if the insn can not be used for rematerialization. */ static cand_t *insn_to_cand; +/* A secondary map, for candidates that involve two insns, where the + second one makes the equivalence. The candidate must not be used + before seeing this activation insn. */ +static cand_t *insn_to_cand_activation; /* Map regno -> candidates can be used for the regno rematerialization. */ @@ -418,30 +425,30 @@ operand_to_remat (rtx_insn *insn) return -1; /* First find a pseudo which can be rematerialized. */ for (reg = id->regs; reg != NULL; reg = reg->next) - /* True FRAME_POINTER_NEEDED might be because we can not follow - changing sp offsets, e.g. alloca is used. If the insn contains - stack pointer in such case, we can not rematerialize it as we - can not know sp offset at a rematerialization place. */ - if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed) - return -1; - else if (reg->type == OP_OUT && ! reg->subreg_p - && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL) - { - /* We permits only one spilled reg. */ - if (found_reg != NULL) - return -1; - found_reg = reg; - } - /* IRA calculates conflicts separately for subregs of two words - pseudo. Even if the pseudo lives, e.g. one its subreg can be - used lately, another subreg hard register can be already used - for something else. In such case, it is not safe to - rematerialize the insn. */ - else if (reg->type == OP_IN && reg->subreg_p - && reg->regno >= FIRST_PSEUDO_REGISTER - && (GET_MODE_SIZE (PSEUDO_REGNO_MODE (reg->regno)) - == 2 * UNITS_PER_WORD)) - return -1; + { + /* True FRAME_POINTER_NEEDED might be because we can not follow + changing sp offsets, e.g. alloca is used. If the insn contains + stack pointer in such case, we can not rematerialize it as we + can not know sp offset at a rematerialization place. */ + if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed) + return -1; + else if (reg->type == OP_OUT && ! reg->subreg_p + && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL) + { + /* We permits only one spilled reg. */ + if (found_reg != NULL) + return -1; + found_reg = reg; + } + /* IRA calculates conflicts separately for subregs of two words + pseudo. Even if the pseudo lives, e.g. one its subreg can be + used lately, another subreg hard register can be already used + for something else. In such case, it is not safe to + rematerialize the insn. */ + if (reg->regno >= FIRST_PSEUDO_REGISTER + && bitmap_bit_p (&subreg_regs, reg->regno)) + return -1; + } if (found_reg == NULL) return -1; if (found_reg->regno < FIRST_PSEUDO_REGISTER) @@ -493,7 +500,7 @@ operand_to_remat (rtx_insn *insn) REGNO. Insert the candidate into the table and set up the corresponding INSN_TO_CAND element. */ static void -create_cand (rtx_insn *insn, int nop, int regno) +create_cand (rtx_insn *insn, int nop, int regno, rtx_insn *activation = NULL) { lra_insn_recog_data_t id = lra_get_insn_recog_data (insn); rtx reg = *id->operand_loc[nop]; @@ -518,6 +525,8 @@ create_cand (rtx_insn *insn, int nop, int regno) cand->next_regno_cand = regno_cands[cand->regno]; regno_cands[cand->regno] = cand; } + if (activation) + insn_to_cand_activation[INSN_UID (activation)] = cand_in_table; } /* Create rematerialization candidates (inserting them into the @@ -536,43 +545,55 @@ create_cands (void) /* Create candidates. */ regno_potential_cand = XCNEWVEC (struct potential_cand, max_reg_num ()); for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) { - rtx set; - int src_regno, dst_regno; - rtx_insn *insn2; lra_insn_recog_data_t id = lra_get_insn_recog_data (insn); - int nop = operand_to_remat (insn); - int regno = -1; - - if ((set = single_set (insn)) != NULL - && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set)) - && ((src_regno = REGNO (SET_SRC (set))) - >= lra_constraint_new_regno_start) - && (dst_regno = REGNO (SET_DEST (set))) >= FIRST_PSEUDO_REGISTER - && reg_renumber[dst_regno] < 0 - && (insn2 = regno_potential_cand[src_regno].insn) != NULL - && BLOCK_FOR_INSN (insn2) == BLOCK_FOR_INSN (insn)) - /* It is an output reload insn after insn can be - rematerialized (potential candidate). */ - create_cand (insn2, regno_potential_cand[src_regno].nop, dst_regno); - if (nop < 0) - goto fail; - gcc_assert (REG_P (*id->operand_loc[nop])); - regno = REGNO (*id->operand_loc[nop]); - gcc_assert (regno >= FIRST_PSEUDO_REGISTER); - if (reg_renumber[regno] < 0) - create_cand (insn, nop, regno); - else + int keep_regno = -1; + rtx set = single_set (insn); + int nop; + + /* See if this is an output reload for a previous insn. */ + if (set != NULL + && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))) + { + rtx dstreg = SET_DEST (set); + int src_regno = REGNO (SET_SRC (set)); + int dst_regno = REGNO (dstreg); + rtx_insn *insn2 = regno_potential_cand[src_regno].insn; + + if (insn2 != NULL + && dst_regno >= FIRST_PSEUDO_REGISTER + && reg_renumber[dst_regno] < 0 + && BLOCK_FOR_INSN (insn2) == BLOCK_FOR_INSN (insn)) + { + create_cand (insn2, regno_potential_cand[src_regno].nop, + dst_regno, insn); + goto done; + } + } + + nop = operand_to_remat (insn); + if (nop >= 0) { - regno_potential_cand[regno].insn = insn; - regno_potential_cand[regno].nop = nop; - goto fail; + gcc_assert (REG_P (*id->operand_loc[nop])); + int regno = REGNO (*id->operand_loc[nop]); + gcc_assert (regno >= FIRST_PSEUDO_REGISTER); + /* If we're setting an unrenumbered pseudo, make a candidate immediately. + If it's an output reload register, save it for later; the code above + looks for output reload insns later on. */ + if (reg_renumber[regno] < 0) + create_cand (insn, nop, regno); + else if (regno >= lra_constraint_new_regno_start) + { + regno_potential_cand[regno].insn = insn; + regno_potential_cand[regno].nop = nop; + keep_regno = regno; + } } - regno = -1; - fail: + + done: for (struct lra_insn_reg *reg = id->regs; reg != NULL; reg = reg->next) - if (reg->type != OP_IN && reg->regno != regno + if (reg->type != OP_IN && reg->regno != keep_regno && reg->regno >= FIRST_PSEUDO_REGISTER) regno_potential_cand[reg->regno].insn = NULL; } @@ -668,6 +689,9 @@ dump_candidates_and_remat_bb_data (void) lra_dump_bitmap_with_title ("avout cands in BB", &get_remat_bb_data (bb)->avout_cands, bb->index); } + fprintf (lra_dump_file, "subreg regs:"); + dump_regset (&subreg_regs, lra_dump_file); + putc ('\n', lra_dump_file); } /* Free all BB data. */ @@ -692,21 +716,24 @@ finish_remat_bb_data (void) -/* Update changed_regs and dead_regs of BB from INSN. */ +/* Update changed_regs, dead_regs, subreg_regs of BB from INSN. */ static void set_bb_regs (basic_block bb, rtx_insn *insn) { lra_insn_recog_data_t id = lra_get_insn_recog_data (insn); + remat_bb_data_t bb_info = get_remat_bb_data (bb); struct lra_insn_reg *reg; for (reg = id->regs; reg != NULL; reg = reg->next) - if (reg->type != OP_IN) - bitmap_set_bit (&get_remat_bb_data (bb)->changed_regs, reg->regno); - else - { - if (find_regno_note (insn, REG_DEAD, (unsigned) reg->regno) != NULL) - bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs, reg->regno); - } + { + unsigned regno = reg->regno; + if (reg->type != OP_IN) + bitmap_set_bit (&bb_info->changed_regs, regno); + else if (find_regno_note (insn, REG_DEAD, regno) != NULL) + bitmap_set_bit (&bb_info->dead_regs, regno); + if (regno >= FIRST_PSEUDO_REGISTER && reg->subreg_p) + bitmap_set_bit (&subreg_regs, regno); + } if (CALL_P (insn)) for (int i = 0; i < call_used_regs_arr_len; i++) bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs, @@ -722,7 +749,7 @@ calculate_local_reg_remat_bb_data (void) FOR_EACH_BB_FN (bb, cfun) FOR_BB_INSNS (bb, insn) - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) set_bb_regs (bb, insn); } @@ -1100,16 +1127,21 @@ do_remat (void) rtx_insn *insn; basic_block bb; bitmap_head avail_cands; + bitmap_head active_cands; bool changed_p = false; /* Living hard regs and hard registers of living pseudos. */ HARD_REG_SET live_hard_regs; bitmap_initialize (&avail_cands, ®_obstack); + bitmap_initialize (&active_cands, ®_obstack); FOR_EACH_BB_FN (bb, cfun) { REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_out (bb)); bitmap_and (&avail_cands, &get_remat_bb_data (bb)->avin_cands, &get_remat_bb_data (bb)->livein_cands); + /* Activating insns are always in the same block as their corresponding + remat insn, so at the start of a block the two bitsets are equal. */ + bitmap_copy (&active_cands, &avail_cands); FOR_BB_INSNS (bb, insn) { if (!NONDEBUG_INSN_P (insn)) @@ -1143,7 +1175,8 @@ do_remat (void) for (cand = regno_cands[src_regno]; cand != NULL; cand = cand->next_regno_cand) - if (bitmap_bit_p (&avail_cands, cand->index)) + if (bitmap_bit_p (&avail_cands, cand->index) + && bitmap_bit_p (&active_cands, cand->index)) break; } int i, hard_regno, nregs; @@ -1237,9 +1270,23 @@ do_remat (void) } bitmap_and_compl_into (&avail_cands, &temp_bitmap); - if ((cand = insn_to_cand[INSN_UID (insn)]) != NULL) - bitmap_set_bit (&avail_cands, cand->index); - + + /* Now see whether a candidate is made active or available + by this insn. */ + cand = insn_to_cand_activation[INSN_UID (insn)]; + if (cand) + bitmap_set_bit (&active_cands, cand->index); + + cand = insn_to_cand[INSN_UID (insn)]; + if (cand != NULL) + { + bitmap_set_bit (&avail_cands, cand->index); + if (cand->reload_regno == -1) + bitmap_set_bit (&active_cands, cand->index); + else + bitmap_clear_bit (&active_cands, cand->index); + } + if (remat_insn != NULL) { HOST_WIDE_INT sp_offset_change = cand_sp_offset - id->sp_offset; @@ -1286,6 +1333,7 @@ do_remat (void) } } bitmap_clear (&avail_cands); + bitmap_clear (&active_cands); return changed_p; } @@ -1314,6 +1362,7 @@ lra_remat (void) lra_rematerialization_iter); timevar_push (TV_LRA_REMAT); insn_to_cand = XCNEWVEC (cand_t, get_max_uid ()); + insn_to_cand_activation = XCNEWVEC (cand_t, get_max_uid ()); regno_cands = XCNEWVEC (cand_t, max_regno); all_cands.create (8000); call_used_regs_arr_len = 0; @@ -1321,10 +1370,11 @@ lra_remat (void) if (call_used_regs[i]) call_used_regs_arr[call_used_regs_arr_len++] = i; initiate_cand_table (); - create_cands (); create_remat_bb_data (); bitmap_initialize (&temp_bitmap, ®_obstack); + bitmap_initialize (&subreg_regs, ®_obstack); calculate_local_reg_remat_bb_data (); + create_cands (); calculate_livein_cands (); calculate_gen_cands (); bitmap_initialize (&all_blocks, ®_obstack); @@ -1335,11 +1385,13 @@ lra_remat (void) result = do_remat (); all_cands.release (); bitmap_clear (&temp_bitmap); + bitmap_clear (&subreg_regs); finish_remat_bb_data (); finish_cand_table (); bitmap_clear (&all_blocks); free (regno_cands); free (insn_to_cand); + free (insn_to_cand_activation); timevar_pop (TV_LRA_REMAT); return result; } diff --git a/contrib/gcc-5.0/gcc/lra.c b/contrib/gcc-5.0/gcc/lra.c index 2efc286005..84c7211dc5 100644 --- a/contrib/gcc-5.0/gcc/lra.c +++ b/contrib/gcc-5.0/gcc/lra.c @@ -1801,20 +1801,29 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after, } if (before != NULL_RTX) { + if (cfun->can_throw_non_call_exceptions) + copy_reg_eh_region_note_forward (insn, before, NULL); emit_insn_before (before, insn); push_insns (PREV_INSN (insn), PREV_INSN (before)); setup_sp_offset (before, PREV_INSN (insn)); } if (after != NULL_RTX) { + if (cfun->can_throw_non_call_exceptions) + copy_reg_eh_region_note_forward (insn, after, NULL); for (last = after; NEXT_INSN (last) != NULL_RTX; last = NEXT_INSN (last)) ; emit_insn_after (after, insn); push_insns (last, insn); setup_sp_offset (after, last); } + if (cfun->can_throw_non_call_exceptions) + { + rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + if (note && !insn_could_throw_p (insn)) + remove_note (insn, note); + } } - /* Replace all references to register OLD_REGNO in *LOC with pseudo diff --git a/contrib/gcc-5.0/gcc/lto-streamer.h b/contrib/gcc-5.0/gcc/lto-streamer.h index b383631a74..15113722c7 100644 --- a/contrib/gcc-5.0/gcc/lto-streamer.h +++ b/contrib/gcc-5.0/gcc/lto-streamer.h @@ -134,7 +134,7 @@ along with GCC; see the file COPYING3. If not see form followed by the data for the string. */ #define LTO_major_version 4 -#define LTO_minor_version 0 +#define LTO_minor_version 1 typedef unsigned char lto_decl_flags_t; diff --git a/contrib/gcc-5.0/gcc/lto/lto-partition.c b/contrib/gcc-5.0/gcc/lto/lto-partition.c index 7d117e9a49..7244eda333 100644 --- a/contrib/gcc-5.0/gcc/lto/lto-partition.c +++ b/contrib/gcc-5.0/gcc/lto/lto-partition.c @@ -1038,8 +1038,8 @@ rename_statics (lto_symtab_encoder_t encoder, symtab_node *node) for (s = symtab_node::get_for_asmname (name); s;) if (!s->externally_visible && ((s->real_symbol_p () - && !DECL_EXTERNAL (node->decl) - && !TREE_PUBLIC (node->decl)) + && !DECL_EXTERNAL (s->decl) + && !TREE_PUBLIC (s->decl)) || may_need_named_section_p (encoder, s)) && (!encoder || lto_symtab_encoder_lookup (encoder, s) != LCC_NOT_FOUND)) diff --git a/contrib/gcc-5.0/gcc/match.pd b/contrib/gcc-5.0/gcc/match.pd index e40720e130..251f2adf0d 100644 --- a/contrib/gcc-5.0/gcc/match.pd +++ b/contrib/gcc-5.0/gcc/match.pd @@ -370,24 +370,31 @@ along with GCC; see the file COPYING3. If not see (ne (bit_and:c (bit_not @0) @1) integer_zerop) (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) && TYPE_PRECISION (TREE_TYPE (@1)) == 1) - (lt @0 @1))) + (if (TYPE_UNSIGNED (TREE_TYPE (@1))) + (lt @0 @1)) + (gt @0 @1))) (simplify (ne (bit_ior:c (bit_not @0) @1) integer_zerop) (if (INTEGRAL_TYPE_P (TREE_TYPE (@1)) && TYPE_PRECISION (TREE_TYPE (@1)) == 1) - (le @0 @1))) + (if (TYPE_UNSIGNED (TREE_TYPE (@1))) + (le @0 @1)) + (ge @0 @1))) /* ~~x -> x */ (simplify (bit_not (bit_not @0)) @0) +/* Disable on GENERIC because of PR68513. */ +#if GIMPLE /* (x & ~m) | (y & m) -> ((x ^ y) & m) ^ x */ (simplify (bit_ior:c (bit_and:c@3 @0 (bit_not @2)) (bit_and:c@4 @1 @2)) (if ((TREE_CODE (@3) != SSA_NAME || has_single_use (@3)) && (TREE_CODE (@4) != SSA_NAME || has_single_use (@4))) (bit_xor (bit_and (bit_xor @0 @1) @2) @0))) +#endif /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */ @@ -747,7 +754,8 @@ along with GCC; see the file COPYING3. If not see /* A truncation to an unsigned type (a zero-extension) should be canonicalized as bitwise and of a mask. */ - (if (final_int && inter_int && inside_int + (if (GIMPLE /* PR70366: doing this in GENERIC breaks -Wconversion. */ + && final_int && inter_int && inside_int && final_prec == inside_prec && final_prec > inter_prec && inter_unsignedp) diff --git a/contrib/gcc-5.0/gcc/modulo-sched.c b/contrib/gcc-5.0/gcc/modulo-sched.c index 22cd21650f..a5da8b42cc 100644 --- a/contrib/gcc-5.0/gcc/modulo-sched.c +++ b/contrib/gcc-5.0/gcc/modulo-sched.c @@ -1023,7 +1023,7 @@ optimize_sc (partial_schedule_ptr ps, ddg_ptr g) int row = SMODULO (branch_cycle, ps->ii); int num_splits = 0; sbitmap must_precede, must_follow, tmp_precede, tmp_follow; - int c; + int min_cycle, c; if (dump_file) fprintf (dump_file, "\nTrying to schedule node %d " @@ -1078,6 +1078,7 @@ optimize_sc (partial_schedule_ptr ps, ddg_ptr g) if (next_ps_i->id == g->closing_branch->cuid) break; + min_cycle = PS_MIN_CYCLE (ps) - SMODULO (PS_MIN_CYCLE (ps), ps->ii); remove_node_from_ps (ps, next_ps_i); success = try_scheduling_node_in_cycle (ps, g->closing_branch->cuid, c, @@ -1117,6 +1118,10 @@ optimize_sc (partial_schedule_ptr ps, ddg_ptr g) ok = true; } + /* This might have been added to a new first stage. */ + if (PS_MIN_CYCLE (ps) < min_cycle) + reset_sched_times (ps, 0); + free (must_precede); free (must_follow); } diff --git a/contrib/gcc-5.0/gcc/omp-low.c b/contrib/gcc-5.0/gcc/omp-low.c index a1ac6a6f14..55afc60ed8 100644 --- a/contrib/gcc-5.0/gcc/omp-low.c +++ b/contrib/gcc-5.0/gcc/omp-low.c @@ -9123,9 +9123,15 @@ expand_omp_target (struct omp_region *region) make_edge (else_bb, new_bb, EDGE_FALLTHRU); device = tmp_var; + gsi = gsi_last_bb (new_bb); + } + else + { + gsi = gsi_last_bb (new_bb); + device = force_gimple_operand_gsi (&gsi, device, true, NULL_TREE, + true, GSI_SAME_STMT); } - gsi = gsi_last_bb (new_bb); t = gimple_omp_target_data_arg (entry_stmt); if (t == NULL) { @@ -12779,7 +12785,8 @@ simd_clone_create (struct cgraph_node *old_node) DECL_STATIC_CONSTRUCTOR (new_decl) = 0; DECL_STATIC_DESTRUCTOR (new_decl) = 0; new_node = old_node->create_version_clone (new_decl, vNULL, NULL); - symtab->call_cgraph_insertion_hooks (new_node); + if (old_node->in_other_partition) + new_node->in_other_partition = 1; } if (new_node == NULL) return new_node; diff --git a/contrib/gcc-5.0/gcc/optabs.c b/contrib/gcc-5.0/gcc/optabs.c index 2c7aef913a..1a0c89c2f1 100644 --- a/contrib/gcc-5.0/gcc/optabs.c +++ b/contrib/gcc-5.0/gcc/optabs.c @@ -1419,6 +1419,7 @@ expand_binop_directly (machine_mode mode, optab binoptab, rtx pat; rtx xop0 = op0, xop1 = op1; rtx swap; + bool canonicalize_op1 = false; /* If it is a commutative operator and the modes would match if we would swap the operands, we can save the conversions. */ @@ -1436,6 +1437,11 @@ expand_binop_directly (machine_mode mode, optab binoptab, xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp); if (!shift_optab_p (binoptab)) xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp); + else if (xmode1 != VOIDmode) + /* Shifts and rotates often use a different mode for op1 from op0; + for VOIDmode constants we don't know the mode, so force it + to be canonicalized using convert_modes. */ + canonicalize_op1 = true; /* In case the insn wants input operands in modes different from those of the actual operands, convert the operands. It would @@ -1450,7 +1456,8 @@ expand_binop_directly (machine_mode mode, optab binoptab, mode0 = xmode0; } - mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode; + mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1) + ? GET_MODE (xop1) : mode); if (xmode1 != VOIDmode && xmode1 != mode1) { xop1 = convert_modes (xmode1, mode1, xop1, unsignedp); @@ -1535,7 +1542,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN ? OPTAB_WIDEN : methods); enum mode_class mclass; - machine_mode wider_mode; + machine_mode wider_mode, inner_mode; rtx libfunc; rtx temp; rtx_insn *entry_last = get_last_insn (); @@ -1551,6 +1558,18 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, op1 = negate_rtx (mode, op1); binoptab = add_optab; } + /* For shifts, constant invalid op1 might be expanded from different + mode than MODE. As those are invalid, force them to a register + to avoid further problems during expansion. */ + else if (CONST_INT_P (op1) + && shift_optab_p (binoptab) + && (inner_mode = (GET_MODE_INNER (mode) == VOIDmode + ? mode : GET_MODE_INNER (mode))) != VOIDmode + && UINTVAL (op1) >= GET_MODE_BITSIZE (inner_mode)) + { + op1 = gen_int_mode (INTVAL (op1), inner_mode); + op1 = force_reg (inner_mode, op1); + } /* Record where to delete back to if we backtrack. */ last = get_last_insn (); diff --git a/contrib/gcc-5.0/gcc/passes.c b/contrib/gcc-5.0/gcc/passes.c index 062ae4f0d1..455f9ba736 100644 --- a/contrib/gcc-5.0/gcc/passes.c +++ b/contrib/gcc-5.0/gcc/passes.c @@ -2208,7 +2208,7 @@ execute_one_ipa_transform_pass (struct cgraph_node *node, check_profile_consistency (pass->static_pass_number, 1, true); if (dump_file) - do_per_function (execute_function_dump, NULL); + do_per_function (execute_function_dump, pass); pass_fini_dump_file (pass); current_pass = NULL; @@ -2345,14 +2345,15 @@ execute_one_pass (opt_pass *pass) check_profile_consistency (pass->static_pass_number, 1, true); verify_interpass_invariants (); - if (dump_file) - do_per_function (execute_function_dump, pass); - if (pass->type == IPA_PASS) + if (pass->type == IPA_PASS + && ((ipa_opt_pass_d *)pass)->function_transform) { struct cgraph_node *node; FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass); } + else if (dump_file) + do_per_function (execute_function_dump, pass); if (!current_function_decl) symtab->process_new_functions (); diff --git a/contrib/gcc-5.0/gcc/postreload.c b/contrib/gcc-5.0/gcc/postreload.c index 58b586a2e4..3a20f9f6d8 100644 --- a/contrib/gcc-5.0/gcc/postreload.c +++ b/contrib/gcc-5.0/gcc/postreload.c @@ -1103,7 +1103,6 @@ static bool reload_combine_recognize_pattern (rtx_insn *insn) { rtx set, reg, src; - unsigned int regno; set = single_set (insn); if (set == NULL_RTX) @@ -1115,7 +1114,20 @@ reload_combine_recognize_pattern (rtx_insn *insn) || hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1) return false; - regno = REGNO (reg); + unsigned int regno = REGNO (reg); + machine_mode mode = GET_MODE (reg); + + if (reg_state[regno].use_index < 0 + || reg_state[regno].use_index >= RELOAD_COMBINE_MAX_USES) + return false; + + for (int i = reg_state[regno].use_index; + i < RELOAD_COMBINE_MAX_USES; i++) + { + struct reg_use *use = reg_state[regno].reg_use + i; + if (GET_MODE (*use->usep) != mode) + return false; + } /* Look for (set (REGX) (CONST_INT)) (set (REGX) (PLUS (REGX) (REGY))) @@ -1137,8 +1149,6 @@ reload_combine_recognize_pattern (rtx_insn *insn) && REG_P (XEXP (src, 1)) && rtx_equal_p (XEXP (src, 0), reg) && !rtx_equal_p (XEXP (src, 1), reg) - && reg_state[regno].use_index >= 0 - && reg_state[regno].use_index < RELOAD_COMBINE_MAX_USES && last_label_ruid < reg_state[regno].use_ruid) { rtx base = XEXP (src, 1); diff --git a/contrib/gcc-5.0/gcc/regstat.c b/contrib/gcc-5.0/gcc/regstat.c index c683a49f0f..a0c8a171e7 100644 --- a/contrib/gcc-5.0/gcc/regstat.c +++ b/contrib/gcc-5.0/gcc/regstat.c @@ -458,7 +458,7 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live) struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); unsigned int regno; - if (!INSN_P (insn)) + if (!NONDEBUG_INSN_P (insn)) continue; /* Process the defs. */ diff --git a/contrib/gcc-5.0/gcc/rtl.h b/contrib/gcc-5.0/gcc/rtl.h index 59c60f5716..fb216b6f7d 100644 --- a/contrib/gcc-5.0/gcc/rtl.h +++ b/contrib/gcc-5.0/gcc/rtl.h @@ -2609,6 +2609,8 @@ extern unsigned int subreg_highpart_offset (machine_mode, machine_mode); extern int byte_lowpart_offset (machine_mode, machine_mode); extern rtx make_safe_from (rtx, rtx); +extern rtx convert_memory_address_addr_space_1 (machine_mode, rtx, + addr_space_t, bool, bool); extern rtx convert_memory_address_addr_space (machine_mode, rtx, addr_space_t); #define convert_memory_address(to_mode,x) \ @@ -3521,6 +3523,8 @@ extern int anti_dependence (const_rtx, const_rtx); extern int canon_anti_dependence (const_rtx, bool, const_rtx, machine_mode, rtx); extern int output_dependence (const_rtx, const_rtx); +extern int canon_output_dependence (const_rtx, bool, + const_rtx, machine_mode, rtx); extern int may_alias_p (const_rtx, const_rtx); extern void init_alias_target (void); extern void init_alias_analysis (void); diff --git a/contrib/gcc-5.0/gcc/rtlanal.c b/contrib/gcc-5.0/gcc/rtlanal.c index 743aad6705..417f9e04eb 100644 --- a/contrib/gcc-5.0/gcc/rtlanal.c +++ b/contrib/gcc-5.0/gcc/rtlanal.c @@ -1325,7 +1325,7 @@ set_noop_p (const_rtx set) if (GET_CODE (dst) == ZERO_EXTRACT) return rtx_equal_p (XEXP (dst, 0), src) - && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx + && !BITS_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx && !side_effects_p (src); if (GET_CODE (dst) == STRICT_LOW_PART) diff --git a/contrib/gcc-5.0/gcc/sched-deps.c b/contrib/gcc-5.0/gcc/sched-deps.c index 459a468ac9..ce1eac8f0f 100644 --- a/contrib/gcc-5.0/gcc/sched-deps.c +++ b/contrib/gcc-5.0/gcc/sched-deps.c @@ -2742,9 +2742,12 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx_insn *insn) return; } - /* Force pending stores to memory in case a trap handler needs them. */ + /* Force pending stores to memory in case a trap handler needs them. + Also force pending loads from memory; loads and stores can segfault + and the signal handler won't be triggered if the trap insn was moved + above load or store insn. */ case TRAP_IF: - flush_pending_lists (deps, insn, true, false); + flush_pending_lists (deps, insn, true, true); break; case PREFETCH: @@ -2893,6 +2896,17 @@ sched_macro_fuse_insns (rtx_insn *insn) } +/* Get the implicit reg pending clobbers for INSN and save them in TEMP. */ +void +get_implicit_reg_pending_clobbers (HARD_REG_SET *temp, rtx_insn *insn) +{ + extract_insn (insn); + preprocess_constraints (insn); + alternative_mask preferred = get_preferred_alternatives (insn); + ira_implicitly_set_insn_hard_regs (temp, preferred); + AND_COMPL_HARD_REG_SET (*temp, ira_no_alloc_regs); +} + /* Analyze an INSN with pattern X to find all dependencies. */ static void sched_analyze_insn (struct deps_desc *deps, rtx x, rtx_insn *insn) @@ -2905,12 +2919,7 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx_insn *insn) if (! reload_completed) { HARD_REG_SET temp; - - extract_insn (insn); - preprocess_constraints (insn); - alternative_mask prefrred = get_preferred_alternatives (insn); - ira_implicitly_set_insn_hard_regs (&temp, prefrred); - AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); + get_implicit_reg_pending_clobbers (&temp, insn); IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp); } @@ -3523,7 +3532,8 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx_insn *insn) { if (deps->last_args_size) add_dependence (insn, deps->last_args_size, REG_DEP_OUTPUT); - deps->last_args_size = insn; + if (!deps->readonly) + deps->last_args_size = insn; } } diff --git a/contrib/gcc-5.0/gcc/sched-int.h b/contrib/gcc-5.0/gcc/sched-int.h index 1cb0e2d344..4cad020512 100644 --- a/contrib/gcc-5.0/gcc/sched-int.h +++ b/contrib/gcc-5.0/gcc/sched-int.h @@ -1346,6 +1346,7 @@ extern void finish_deps_global (void); extern void deps_analyze_insn (struct deps_desc *, rtx_insn *); extern void remove_from_deps (struct deps_desc *, rtx_insn *); extern void init_insn_reg_pressure_info (rtx); +extern void get_implicit_reg_pending_clobbers (HARD_REG_SET *, rtx_insn *); extern dw_t get_dep_weak (ds_t, ds_t); extern ds_t set_dep_weak (ds_t, ds_t, dw_t); diff --git a/contrib/gcc-5.0/gcc/sel-sched-ir.c b/contrib/gcc-5.0/gcc/sel-sched-ir.c index 94f6c43a28..c681d3710e 100644 --- a/contrib/gcc-5.0/gcc/sel-sched-ir.c +++ b/contrib/gcc-5.0/gcc/sel-sched-ir.c @@ -1891,12 +1891,16 @@ merge_expr (expr_t to, expr_t from, insn_t split_point) /* Make sure that speculative pattern is propagated into exprs that have non-speculative one. This will provide us with consistent speculative bits and speculative patterns inside expr. */ - if ((EXPR_SPEC_DONE_DS (from) != 0 - && EXPR_SPEC_DONE_DS (to) == 0) - /* Do likewise for volatile insns, so that we always retain - the may_trap_p bit on the resulting expression. */ - || (VINSN_MAY_TRAP_P (EXPR_VINSN (from)) - && !VINSN_MAY_TRAP_P (EXPR_VINSN (to)))) + if (EXPR_SPEC_DONE_DS (to) == 0 + && (EXPR_SPEC_DONE_DS (from) != 0 + /* Do likewise for volatile insns, so that we always retain + the may_trap_p bit on the resulting expression. However, + avoid propagating the trapping bit into the instructions + already speculated. This would result in replacing the + speculative pattern with the non-speculative one and breaking + the speculation support. */ + || (!VINSN_MAY_TRAP_P (EXPR_VINSN (to)) + && VINSN_MAY_TRAP_P (EXPR_VINSN (from))))) change_vinsn_in_expr (to, EXPR_VINSN (from)); merge_expr_data (to, from, split_point); @@ -2670,6 +2674,23 @@ maybe_downgrade_id_to_use (idata_t id, insn_t insn) IDATA_TYPE (id) = USE; } +/* Setup implicit register clobbers calculated by sched-deps for INSN + before reload and save them in ID. */ +static void +setup_id_implicit_regs (idata_t id, insn_t insn) +{ + if (reload_completed) + return; + + HARD_REG_SET temp; + unsigned regno; + hard_reg_set_iterator hrsi; + + get_implicit_reg_pending_clobbers (&temp, insn); + EXECUTE_IF_SET_IN_HARD_REG_SET (temp, 0, regno, hrsi) + SET_REGNO_REG_SET (IDATA_REG_SETS (id), regno); +} + /* Setup register sets describing INSN in ID. */ static void setup_id_reg_sets (idata_t id, insn_t insn) @@ -2724,6 +2745,9 @@ setup_id_reg_sets (idata_t id, insn_t insn) } } + /* Also get implicit reg clobbers from sched-deps. */ + setup_id_implicit_regs (id, insn); + return_regset_to_pool (tmp); } @@ -2755,20 +2779,18 @@ deps_init_id (idata_t id, insn_t insn, bool force_unique_p) deps_init_id_data.force_use_p = false; init_deps (dc, false); - memcpy (&deps_init_id_sched_deps_info, &const_deps_init_id_sched_deps_info, sizeof (deps_init_id_sched_deps_info)); - if (spec_info != NULL) deps_init_id_sched_deps_info.generate_spec_deps = 1; - sched_deps_info = &deps_init_id_sched_deps_info; deps_analyze_insn (dc, insn); + /* Implicit reg clobbers received from sched-deps separately. */ + setup_id_implicit_regs (id, insn); free_deps (dc); - deps_init_id_data.id = NULL; } @@ -4104,11 +4126,14 @@ get_seqno_by_preds (rtx_insn *insn) insn_t *preds; int n, i, seqno; - while (tmp != head) + /* Loop backwards from INSN to HEAD including both. */ + while (1) { - tmp = PREV_INSN (tmp); if (INSN_P (tmp)) - return INSN_SEQNO (tmp); + return INSN_SEQNO (tmp); + if (tmp == head) + break; + tmp = PREV_INSN (tmp); } cfg_preds (bb, &preds, &n); diff --git a/contrib/gcc-5.0/gcc/sel-sched.c b/contrib/gcc-5.0/gcc/sel-sched.c index 0a322a84dc..dab06ec10d 100644 --- a/contrib/gcc-5.0/gcc/sel-sched.c +++ b/contrib/gcc-5.0/gcc/sel-sched.c @@ -1486,31 +1486,44 @@ choose_best_pseudo_reg (regset used_regs, gcc_assert (mode == GET_MODE (dest)); orig_regno = REGNO (dest); - if (!REGNO_REG_SET_P (used_regs, orig_regno)) - { - if (orig_regno < FIRST_PSEUDO_REGISTER) - { - gcc_assert (df_regs_ever_live_p (orig_regno)); + /* Check that nothing in used_regs intersects with orig_regno. When + we have a hard reg here, still loop over hard_regno_nregs. */ + if (HARD_REGISTER_NUM_P (orig_regno)) + { + int j, n; + for (j = 0, n = hard_regno_nregs[orig_regno][mode]; j < n; j++) + if (REGNO_REG_SET_P (used_regs, orig_regno + j)) + break; + if (j < n) + continue; + } + else + { + if (REGNO_REG_SET_P (used_regs, orig_regno)) + continue; + } + if (HARD_REGISTER_NUM_P (orig_regno)) + { + gcc_assert (df_regs_ever_live_p (orig_regno)); - /* For hard registers, we have to check hardware imposed - limitations (frame/stack registers, calls crossed). */ - if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, - orig_regno)) - { - /* Don't let register cross a call if it doesn't already - cross one. This condition is written in accordance with - that in sched-deps.c sched_analyze_reg(). */ - if (!reg_rename_p->crosses_call - || REG_N_CALLS_CROSSED (orig_regno) > 0) - return gen_rtx_REG (mode, orig_regno); - } + /* For hard registers, we have to check hardware imposed + limitations (frame/stack registers, calls crossed). */ + if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, + orig_regno)) + { + /* Don't let register cross a call if it doesn't already + cross one. This condition is written in accordance with + that in sched-deps.c sched_analyze_reg(). */ + if (!reg_rename_p->crosses_call + || REG_N_CALLS_CROSSED (orig_regno) > 0) + return gen_rtx_REG (mode, orig_regno); + } - bad_hard_regs = true; - } - else - return dest; - } - } + bad_hard_regs = true; + } + else + return dest; + } *is_orig_reg_p_ptr = false; diff --git a/contrib/gcc-5.0/gcc/shrink-wrap.c b/contrib/gcc-5.0/gcc/shrink-wrap.c index 3928f3d8fa..63be1bd80e 100644 --- a/contrib/gcc-5.0/gcc/shrink-wrap.c +++ b/contrib/gcc-5.0/gcc/shrink-wrap.c @@ -79,6 +79,7 @@ along with GCC; see the file COPYING3. If not see #include "shrink-wrap.h" #include "regcprop.h" #include "rtl-iter.h" +#include "valtrack.h" #ifdef HAVE_simple_return @@ -191,7 +192,8 @@ static bool move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn, const HARD_REG_SET uses, const HARD_REG_SET defs, - bool *split_p) + bool *split_p, + struct dead_debug_local *debug) { rtx set, src, dest; bitmap live_out, live_in, bb_uses, bb_defs; @@ -200,6 +202,8 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn, unsigned int end_sregno = FIRST_PSEUDO_REGISTER; basic_block next_block; edge live_edge; + rtx_insn *dinsn; + df_ref def; /* Look for a simple register assignment. We don't use single_set here because we can't deal with any CLOBBERs, USEs, or REG_UNUSED secondary @@ -344,6 +348,20 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn, move it as far as we can. */ do { + if (MAY_HAVE_DEBUG_INSNS) + { + FOR_BB_INSNS_REVERSE (bb, dinsn) + if (DEBUG_INSN_P (dinsn)) + { + df_ref use; + FOR_EACH_INSN_USE (use, dinsn) + if (refers_to_regno_p (dregno, end_dregno, + DF_REF_REG (use), (rtx *) NULL)) + dead_debug_add (debug, use, DF_REF_REGNO (use)); + } + else if (dinsn == insn) + break; + } live_out = df_get_live_out (bb); live_in = df_get_live_in (next_block); bb = next_block; @@ -426,6 +444,12 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn, SET_REGNO_REG_SET (bb_uses, i); } + /* Insert debug temps for dead REGs used in subsequent debug insns. */ + if (debug->used && !bitmap_empty_p (debug->used)) + FOR_EACH_INSN_DEF (def, insn) + dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn, + DEBUG_TEMP_BEFORE_WITH_VALUE); + emit_insn_after (PATTERN (insn), bb_note (bb)); delete_insn (insn); return true; @@ -446,6 +470,8 @@ prepare_shrink_wrap (basic_block entry_block) HARD_REG_SET uses, defs; df_ref def, use; bool split_p = false; + unsigned int i; + struct dead_debug_local debug; if (JUMP_P (BB_END (entry_block))) { @@ -456,19 +482,22 @@ prepare_shrink_wrap (basic_block entry_block) copyprop_hardreg_forward_bb_without_debug_insn (entry_block); } + dead_debug_local_init (&debug, NULL, NULL); CLEAR_HARD_REG_SET (uses); CLEAR_HARD_REG_SET (defs); + FOR_BB_INSNS_REVERSE_SAFE (entry_block, insn, curr) if (NONDEBUG_INSN_P (insn) && !move_insn_for_shrink_wrap (entry_block, insn, uses, defs, - &split_p)) + &split_p, &debug)) { /* Add all defined registers to DEFs. */ FOR_EACH_INSN_DEF (def, insn) { x = DF_REF_REG (def); if (REG_P (x) && HARD_REGISTER_P (x)) - SET_HARD_REG_BIT (defs, REGNO (x)); + for (i = REGNO (x); i < END_REGNO (x); i++) + SET_HARD_REG_BIT (defs, i); } /* Add all used registers to USESs. */ @@ -476,9 +505,12 @@ prepare_shrink_wrap (basic_block entry_block) { x = DF_REF_REG (use); if (REG_P (x) && HARD_REGISTER_P (x)) - SET_HARD_REG_BIT (uses, REGNO (x)); + for (i = REGNO (x); i < END_REGNO (x); i++) + SET_HARD_REG_BIT (uses, i); } } + + dead_debug_local_finish (&debug, NULL); } /* Create a copy of BB instructions and insert at BEFORE. Redirect diff --git a/contrib/gcc-5.0/gcc/simplify-rtx.c b/contrib/gcc-5.0/gcc/simplify-rtx.c index cdad71fa3f..c85ae3e192 100644 --- a/contrib/gcc-5.0/gcc/simplify-rtx.c +++ b/contrib/gcc-5.0/gcc/simplify-rtx.c @@ -1438,7 +1438,14 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op) && REG_P (SUBREG_REG (op)) && REG_POINTER (SUBREG_REG (op)) && GET_MODE (SUBREG_REG (op)) == Pmode))) - return convert_memory_address (Pmode, op); + { + temp + = convert_memory_address_addr_space_1 (Pmode, op, + ADDR_SPACE_GENERIC, false, + true); + if (temp) + return temp; + } #endif break; @@ -1559,7 +1566,14 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op) && REG_P (SUBREG_REG (op)) && REG_POINTER (SUBREG_REG (op)) && GET_MODE (SUBREG_REG (op)) == Pmode))) - return convert_memory_address (Pmode, op); + { + temp + = convert_memory_address_addr_space_1 (Pmode, op, + ADDR_SPACE_GENERIC, false, + true); + if (temp) + return temp; + } #endif break; diff --git a/contrib/gcc-5.0/gcc/stmt.c b/contrib/gcc-5.0/gcc/stmt.c index 45dc45fd04..6c62a12960 100644 --- a/contrib/gcc-5.0/gcc/stmt.c +++ b/contrib/gcc-5.0/gcc/stmt.c @@ -342,13 +342,7 @@ parse_output_constraint (const char **constraint_p, int operand_num, else if (insn_extra_memory_constraint (cn)) *allows_mem = true; else - { - /* Otherwise we can't assume anything about the nature of - the constraint except that it isn't purely registers. - Treat it like "g" and hope for the best. */ - *allows_reg = true; - *allows_mem = true; - } + insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem); break; } @@ -465,13 +459,7 @@ parse_input_constraint (const char **constraint_p, int input_num, else if (insn_extra_memory_constraint (cn)) *allows_mem = true; else - { - /* Otherwise we can't assume anything about the nature of - the constraint except that it isn't purely registers. - Treat it like "g" and hope for the best. */ - *allows_reg = true; - *allows_mem = true; - } + insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem); break; } diff --git a/contrib/gcc-5.0/gcc/targhooks.c b/contrib/gcc-5.0/gcc/targhooks.c index 0c14103766..003e9ef97d 100644 --- a/contrib/gcc-5.0/gcc/targhooks.c +++ b/contrib/gcc-5.0/gcc/targhooks.c @@ -1312,8 +1312,12 @@ bool default_target_option_pragma_parse (tree ARG_UNUSED (args), tree ARG_UNUSED (pop_target)) { - warning (OPT_Wpragmas, - "#pragma GCC target is not supported for this machine"); + /* If args is NULL the caller is handle_pragma_pop_options (). In that case, + emit no warning because "#pragma GCC pop_target" is valid on targets that + do not have the "target" pragma. */ + if (args) + warning (OPT_Wpragmas, + "#pragma GCC target is not supported for this machine"); return false; } diff --git a/contrib/gcc-5.0/gcc/tree-cfg.c b/contrib/gcc-5.0/gcc/tree-cfg.c index 64bdc92e68..7665477541 100644 --- a/contrib/gcc-5.0/gcc/tree-cfg.c +++ b/contrib/gcc-5.0/gcc/tree-cfg.c @@ -2927,10 +2927,10 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) } else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) && TYPE_MODE (TREE_TYPE (t)) != BLKmode - && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t))) + && (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (t))) != tree_to_uhwi (t1))) { - error ("mode precision of non-integral result does not " + error ("mode size of non-integral result does not " "match field size of BIT_FIELD_REF"); return t; } diff --git a/contrib/gcc-5.0/gcc/tree-chrec.c b/contrib/gcc-5.0/gcc/tree-chrec.c index b599c2c3e5..1d7bc47192 100644 --- a/contrib/gcc-5.0/gcc/tree-chrec.c +++ b/contrib/gcc-5.0/gcc/tree-chrec.c @@ -746,12 +746,12 @@ hide_evolution_in_other_loops_than_loop (tree chrec, /* There is no evolution in this loop. */ return initial_condition (chrec); + else if (flow_loop_nested_p (loop, chloop)) + return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec), + loop_num); + else - { - gcc_assert (flow_loop_nested_p (loop, chloop)); - return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec), - loop_num); - } + return chrec_dont_know; default: return chrec; @@ -1464,11 +1464,11 @@ eq_evolutions_p (const_tree chrec0, const_tree chrec1) if (chrec0 == chrec1) return true; + if (! types_compatible_p (TREE_TYPE (chrec0), TREE_TYPE (chrec1))) + return false; + switch (TREE_CODE (chrec0)) { - case INTEGER_CST: - return operand_equal_p (chrec0, chrec1, 0); - case POLYNOMIAL_CHREC: return (CHREC_VARIABLE (chrec0) == CHREC_VARIABLE (chrec1) && eq_evolutions_p (CHREC_LEFT (chrec0), CHREC_LEFT (chrec1)) @@ -1483,8 +1483,12 @@ eq_evolutions_p (const_tree chrec0, const_tree chrec1) && eq_evolutions_p (TREE_OPERAND (chrec0, 1), TREE_OPERAND (chrec1, 1)); + CASE_CONVERT: + return eq_evolutions_p (TREE_OPERAND (chrec0, 0), + TREE_OPERAND (chrec1, 0)); + default: - return false; + return operand_equal_p (chrec0, chrec1, 0); } } diff --git a/contrib/gcc-5.0/gcc/tree-data-ref.c b/contrib/gcc-5.0/gcc/tree-data-ref.c index 57e26d1d95..410fd53a27 100644 --- a/contrib/gcc-5.0/gcc/tree-data-ref.c +++ b/contrib/gcc-5.0/gcc/tree-data-ref.c @@ -1534,13 +1534,14 @@ initialize_data_dependence_relation (struct data_reference *a, /* The case where the references are exactly the same. */ if (operand_equal_p (DR_REF (a), DR_REF (b), 0)) { - if (loop_nest.exists () - && !object_address_invariant_in_loop_p (loop_nest[0], - DR_BASE_OBJECT (a))) - { - DDR_ARE_DEPENDENT (res) = chrec_dont_know; - return res; - } + if ((loop_nest.exists () + && !object_address_invariant_in_loop_p (loop_nest[0], + DR_BASE_OBJECT (a))) + || DR_NUM_DIMENSIONS (a) == 0) + { + DDR_ARE_DEPENDENT (res) = chrec_dont_know; + return res; + } DDR_AFFINE_P (res) = true; DDR_ARE_DEPENDENT (res) = NULL_TREE; DDR_SUBSCRIPTS (res).create (DR_NUM_DIMENSIONS (a)); @@ -1572,9 +1573,9 @@ initialize_data_dependence_relation (struct data_reference *a, /* If the base of the object is not invariant in the loop nest, we cannot analyze it. TODO -- in fact, it would suffice to record that there may be arbitrary dependences in the loops where the base object varies. */ - if (loop_nest.exists () - && !object_address_invariant_in_loop_p (loop_nest[0], - DR_BASE_OBJECT (a))) + if ((loop_nest.exists () + && !object_address_invariant_in_loop_p (loop_nest[0], DR_BASE_OBJECT (a))) + || DR_NUM_DIMENSIONS (a) == 0) { DDR_ARE_DEPENDENT (res) = chrec_dont_know; return res; diff --git a/contrib/gcc-5.0/gcc/tree-inline.c b/contrib/gcc-5.0/gcc/tree-inline.c index 8ca8824f0f..83fb5d3eb3 100644 --- a/contrib/gcc-5.0/gcc/tree-inline.c +++ b/contrib/gcc-5.0/gcc/tree-inline.c @@ -649,7 +649,8 @@ remap_decls (tree decls, vec **nonlocalized_list, /* We need to add this variable to the local decls as otherwise nothing else will do so. */ if (TREE_CODE (old_var) == VAR_DECL - && ! DECL_EXTERNAL (old_var)) + && ! DECL_EXTERNAL (old_var) + && cfun) add_local_decl (cfun, old_var); if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE) && !DECL_IGNORED_P (old_var) @@ -872,7 +873,7 @@ is_parm (tree decl) static unsigned short remap_dependence_clique (copy_body_data *id, unsigned short clique) { - if (clique == 0) + if (clique == 0 || processing_debug_stmt) return 0; if (!id->dependence_map) id->dependence_map @@ -4111,7 +4112,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights) return 0; else if (is_inexpensive_builtin (decl)) return weights->target_builtin_call_cost; - else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) + else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) { /* We canonicalize x * x to pow (x, 2.0) with -ffast-math, so specialize the cheap expansion we do here. diff --git a/contrib/gcc-5.0/gcc/tree-nested.c b/contrib/gcc-5.0/gcc/tree-nested.c index 4991219c19..4be86682d0 100644 --- a/contrib/gcc-5.0/gcc/tree-nested.c +++ b/contrib/gcc-5.0/gcc/tree-nested.c @@ -1344,7 +1344,7 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, { wi->val_only = true; wi->is_lhs = false; - *handled_ops_p = true; + *handled_ops_p = false; return NULL_TREE; } break; diff --git a/contrib/gcc-5.0/gcc/tree-parloops.c b/contrib/gcc-5.0/gcc/tree-parloops.c index 62a6444e66..c3929a1244 100644 --- a/contrib/gcc-5.0/gcc/tree-parloops.c +++ b/contrib/gcc-5.0/gcc/tree-parloops.c @@ -741,6 +741,7 @@ eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi, } else if (gimple_clobber_p (stmt)) { + unlink_stmt_vdef (stmt); stmt = gimple_build_nop (); gsi_replace (gsi, stmt, false); dta.changed = true; diff --git a/contrib/gcc-5.0/gcc/tree-predcom.c b/contrib/gcc-5.0/gcc/tree-predcom.c index 03a38b4de8..8f6a75ec94 100644 --- a/contrib/gcc-5.0/gcc/tree-predcom.c +++ b/contrib/gcc-5.0/gcc/tree-predcom.c @@ -252,6 +252,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-affine.h" #include "tree-inline.h" #include "wide-int-print.h" +#include "builtins.h" /* The maximum number of iterations between the considered memory references. */ @@ -1424,6 +1425,8 @@ ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts) addr = force_gimple_operand_1 (unshare_expr (addr), stmts, is_gimple_mem_ref_addr, NULL_TREE); tree alias_ptr = fold_convert (reference_alias_ptr_type (DR_REF (dr)), coff); + tree type = build_aligned_type (TREE_TYPE (DR_REF (dr)), + get_object_alignment (DR_REF (dr))); /* While data-ref analysis punts on bit offsets it still handles bitfield accesses at byte boundaries. Cope with that. Note that we cannot simply re-apply the outer COMPONENT_REF because the @@ -1435,12 +1438,11 @@ ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts) { tree field = TREE_OPERAND (DR_REF (dr), 1); return build3 (BIT_FIELD_REF, TREE_TYPE (DR_REF (dr)), - build2 (MEM_REF, DECL_BIT_FIELD_TYPE (field), - addr, alias_ptr), + build2 (MEM_REF, type, addr, alias_ptr), DECL_SIZE (field), bitsize_zero_node); } else - return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), addr, alias_ptr); + return fold_build2 (MEM_REF, type, addr, alias_ptr); } /* Get the initialization expression for the INDEX-th temporary variable diff --git a/contrib/gcc-5.0/gcc/tree-scalar-evolution.c b/contrib/gcc-5.0/gcc/tree-scalar-evolution.c index 1b457059d0..6f640b82f3 100644 --- a/contrib/gcc-5.0/gcc/tree-scalar-evolution.c +++ b/contrib/gcc-5.0/gcc/tree-scalar-evolution.c @@ -1724,7 +1724,7 @@ static tree interpret_rhs_expr (struct loop *loop, gimple at_stmt, tree type, tree rhs1, enum tree_code code, tree rhs2) { - tree res, chrec1, chrec2; + tree res, chrec1, chrec2, ctype; gimple def; if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS) @@ -1818,30 +1818,63 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, case PLUS_EXPR: chrec1 = analyze_scalar_evolution (loop, rhs1); chrec2 = analyze_scalar_evolution (loop, rhs2); - chrec1 = chrec_convert (type, chrec1, at_stmt); - chrec2 = chrec_convert (type, chrec2, at_stmt); + ctype = type; + /* When the stmt is conditionally executed re-write the CHREC + into a form that has well-defined behavior on overflow. */ + if (at_stmt + && INTEGRAL_TYPE_P (type) + && ! TYPE_OVERFLOW_WRAPS (type) + && ! dominated_by_p (CDI_DOMINATORS, loop->latch, + gimple_bb (at_stmt))) + ctype = unsigned_type_for (type); + chrec1 = chrec_convert (ctype, chrec1, at_stmt); + chrec2 = chrec_convert (ctype, chrec2, at_stmt); chrec1 = instantiate_parameters (loop, chrec1); chrec2 = instantiate_parameters (loop, chrec2); - res = chrec_fold_plus (type, chrec1, chrec2); + res = chrec_fold_plus (ctype, chrec1, chrec2); + if (type != ctype) + res = chrec_convert (type, res, at_stmt); break; case MINUS_EXPR: chrec1 = analyze_scalar_evolution (loop, rhs1); chrec2 = analyze_scalar_evolution (loop, rhs2); - chrec1 = chrec_convert (type, chrec1, at_stmt); - chrec2 = chrec_convert (type, chrec2, at_stmt); + ctype = type; + /* When the stmt is conditionally executed re-write the CHREC + into a form that has well-defined behavior on overflow. */ + if (at_stmt + && INTEGRAL_TYPE_P (type) + && ! TYPE_OVERFLOW_WRAPS (type) + && ! dominated_by_p (CDI_DOMINATORS, + loop->latch, gimple_bb (at_stmt))) + ctype = unsigned_type_for (type); + chrec1 = chrec_convert (ctype, chrec1, at_stmt); + chrec2 = chrec_convert (ctype, chrec2, at_stmt); chrec1 = instantiate_parameters (loop, chrec1); chrec2 = instantiate_parameters (loop, chrec2); - res = chrec_fold_minus (type, chrec1, chrec2); + res = chrec_fold_minus (ctype, chrec1, chrec2); + if (type != ctype) + res = chrec_convert (type, res, at_stmt); break; case NEGATE_EXPR: chrec1 = analyze_scalar_evolution (loop, rhs1); - chrec1 = chrec_convert (type, chrec1, at_stmt); + ctype = type; + /* When the stmt is conditionally executed re-write the CHREC + into a form that has well-defined behavior on overflow. */ + if (at_stmt + && INTEGRAL_TYPE_P (type) + && ! TYPE_OVERFLOW_WRAPS (type) + && ! dominated_by_p (CDI_DOMINATORS, + loop->latch, gimple_bb (at_stmt))) + ctype = unsigned_type_for (type); + chrec1 = chrec_convert (ctype, chrec1, at_stmt); /* TYPE may be integer, real or complex, so use fold_convert. */ chrec1 = instantiate_parameters (loop, chrec1); - res = chrec_fold_multiply (type, chrec1, - fold_convert (type, integer_minus_one_node)); + res = chrec_fold_multiply (ctype, chrec1, + fold_convert (ctype, integer_minus_one_node)); + if (type != ctype) + res = chrec_convert (type, res, at_stmt); break; case BIT_NOT_EXPR: @@ -1857,11 +1890,22 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, case MULT_EXPR: chrec1 = analyze_scalar_evolution (loop, rhs1); chrec2 = analyze_scalar_evolution (loop, rhs2); - chrec1 = chrec_convert (type, chrec1, at_stmt); - chrec2 = chrec_convert (type, chrec2, at_stmt); + ctype = type; + /* When the stmt is conditionally executed re-write the CHREC + into a form that has well-defined behavior on overflow. */ + if (at_stmt + && INTEGRAL_TYPE_P (type) + && ! TYPE_OVERFLOW_WRAPS (type) + && ! dominated_by_p (CDI_DOMINATORS, + loop->latch, gimple_bb (at_stmt))) + ctype = unsigned_type_for (type); + chrec1 = chrec_convert (ctype, chrec1, at_stmt); + chrec2 = chrec_convert (ctype, chrec2, at_stmt); chrec1 = instantiate_parameters (loop, chrec1); chrec2 = instantiate_parameters (loop, chrec2); - res = chrec_fold_multiply (type, chrec1, chrec2); + res = chrec_fold_multiply (ctype, chrec1, chrec2); + if (type != ctype) + res = chrec_convert (type, res, at_stmt); break; CASE_CONVERT: diff --git a/contrib/gcc-5.0/gcc/tree-sra.c b/contrib/gcc-5.0/gcc/tree-sra.c index 7d713c6034..b2e9190cce 100644 --- a/contrib/gcc-5.0/gcc/tree-sra.c +++ b/contrib/gcc-5.0/gcc/tree-sra.c @@ -1589,7 +1589,7 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset, } else { - off = build_int_cst (reference_alias_ptr_type (base), + off = build_int_cst (reference_alias_ptr_type (prev_base), base_offset + offset / BITS_PER_UNIT); base = build_fold_addr_expr (unshare_expr (base)); } @@ -2329,7 +2329,7 @@ analyze_access_subtree (struct access *root, struct access *parent, if (covered_to < limit) hole = true; - if (scalar) + if (scalar || !allow_replacements) root->grp_total_scalarization = 0; } @@ -3242,6 +3242,7 @@ sra_modify_assign (gimple stmt, gimple_stmt_iterator *gsi) } else if (racc && !racc->grp_unscalarized_data + && !racc->grp_unscalarizable_region && TREE_CODE (lhs) == SSA_NAME && !access_has_replacements_p (racc)) { @@ -3405,7 +3406,8 @@ sra_modify_assign (gimple stmt, gimple_stmt_iterator *gsi) else { if (access_has_children_p (racc) - && !racc->grp_unscalarized_data) + && !racc->grp_unscalarized_data + && TREE_CODE (lhs) != SSA_NAME) { if (dump_file) { @@ -4607,6 +4609,8 @@ replace_removed_params_ssa_names (tree old_name, gimple stmt, repl = get_replaced_param_substitute (adj); new_name = make_ssa_name (repl, stmt); + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name) + = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name); if (dump_file) { diff --git a/contrib/gcc-5.0/gcc/tree-ssa-alias.c b/contrib/gcc-5.0/gcc/tree-ssa-alias.c index 82160d2834..f783ad515f 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-alias.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-alias.c @@ -1109,12 +1109,8 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1)); /* If the alias set for a pointer access is zero all bets are off. */ - if (base1_alias_set == -1) - base1_alias_set = get_deref_alias_set (ptrtype1); if (base1_alias_set == 0) return true; - if (base2_alias_set == -1) - base2_alias_set = get_alias_set (base2); /* When we are trying to disambiguate an access with a pointer dereference as base versus one with a decl as base we can use both the size @@ -1281,13 +1277,8 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, ptrtype2 = TREE_TYPE (TREE_OPERAND (base2, 1)); /* If the alias set for a pointer access is zero all bets are off. */ - if (base1_alias_set == -1) - base1_alias_set = get_deref_alias_set (ptrtype1); - if (base1_alias_set == 0) - return true; - if (base2_alias_set == -1) - base2_alias_set = get_deref_alias_set (ptrtype2); - if (base2_alias_set == 0) + if (base1_alias_set == 0 + || base2_alias_set == 0) return true; /* If both references are through the same type, they do not alias @@ -1462,7 +1453,8 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) if (var1_p && ind2_p) return indirect_ref_may_alias_decl_p (ref2->ref, base2, offset2, max_size2, - ao_ref_alias_set (ref2), -1, + ao_ref_alias_set (ref2), + ao_ref_base_alias_set (ref2), ref1->ref, base1, offset1, max_size1, ao_ref_alias_set (ref1), @@ -1471,10 +1463,12 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) else if (ind1_p && ind2_p) return indirect_refs_may_alias_p (ref1->ref, base1, offset1, max_size1, - ao_ref_alias_set (ref1), -1, + ao_ref_alias_set (ref1), + ao_ref_base_alias_set (ref1), ref2->ref, base2, offset2, max_size2, - ao_ref_alias_set (ref2), -1, + ao_ref_alias_set (ref2), + ao_ref_base_alias_set (ref2), tbaa_p); /* We really do not want to end up here, but returning true is safe. */ diff --git a/contrib/gcc-5.0/gcc/tree-ssa-dom.c b/contrib/gcc-5.0/gcc/tree-ssa-dom.c index 9690004ec1..f33ca0e010 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-dom.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-dom.c @@ -263,7 +263,7 @@ static struct opt_stats_d opt_stats; /* Local functions. */ static void optimize_stmt (basic_block, gimple_stmt_iterator); -static tree lookup_avail_expr (gimple, bool); +static tree lookup_avail_expr (gimple, bool, bool = true); static hashval_t avail_expr_hash (const void *); static void htab_statistics (FILE *, const hash_table &); @@ -2496,7 +2496,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si) else new_stmt = gimple_build_assign (rhs, lhs); gimple_set_vuse (new_stmt, gimple_vuse (stmt)); - cached_lhs = lookup_avail_expr (new_stmt, false); + cached_lhs = lookup_avail_expr (new_stmt, false, false); if (cached_lhs && rhs == cached_lhs) { @@ -2603,7 +2603,7 @@ vuse_eq (ao_ref *, tree vuse1, unsigned int cnt, void *data) we finish processing this block and its children. */ static tree -lookup_avail_expr (gimple stmt, bool insert) +lookup_avail_expr (gimple stmt, bool insert, bool tbaa_p) { expr_hash_elt **slot; tree lhs; @@ -2671,7 +2671,8 @@ lookup_avail_expr (gimple stmt, bool insert) if (!(vuse1 && vuse2 && gimple_assign_single_p (stmt) && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME - && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)), true) + && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)), + ref.base_alias_set = ref.ref_alias_set = tbaa_p ? -1 : 0, true) && walk_non_aliased_vuses (&ref, vuse2, vuse_eq, NULL, NULL, vuse1) != NULL)) { diff --git a/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c b/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c index 93f92f33a5..a1ba1e09d7 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c @@ -1517,7 +1517,7 @@ defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2) || GIMPLE_BINARY_RHS || GIMPLE_UNARY_RHS || GIMPLE_SINGLE_RHS) - extract_ops_from_tree_1 (name, &code1, &arg11, &arg21, &arg31); + extract_ops_from_tree (name, &code1, &arg11, &arg21, &arg31); *code = code1; *arg1 = arg11; 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 251b35fe98..f97c81912a 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-loop-ivcanon.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-loop-ivcanon.c @@ -1193,38 +1193,6 @@ canonicalize_induction_variables (void) return 0; } -/* Propagate VAL into all uses of SSA_NAME. */ - -static void -propagate_into_all_uses (tree ssa_name, tree val) -{ - imm_use_iterator iter; - gimple use_stmt; - - FOR_EACH_IMM_USE_STMT (use_stmt, iter, ssa_name) - { - gimple_stmt_iterator use_stmt_gsi = gsi_for_stmt (use_stmt); - use_operand_p use; - - FOR_EACH_IMM_USE_ON_STMT (use, iter) - SET_USE (use, val); - - if (is_gimple_assign (use_stmt) - && get_gimple_rhs_class (gimple_assign_rhs_code (use_stmt)) - == GIMPLE_SINGLE_RHS) - { - tree rhs = gimple_assign_rhs1 (use_stmt); - - if (TREE_CODE (rhs) == ADDR_EXPR) - recompute_tree_invariant_for_addr_expr (rhs); - } - - fold_stmt_inplace (&use_stmt_gsi); - update_stmt (use_stmt); - maybe_clean_or_replace_eh_stmt (use_stmt, use_stmt); - } -} - /* Propagate constant SSA_NAMEs defined in basic block BB. */ static void @@ -1237,9 +1205,11 @@ propagate_constants_for_unrolling (basic_block bb) tree result = gimple_phi_result (phi); tree arg = gimple_phi_arg_def (phi, 0); - if (gimple_phi_num_args (phi) == 1 && TREE_CODE (arg) == INTEGER_CST) + if (! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (result) + && gimple_phi_num_args (phi) == 1 + && TREE_CODE (arg) == INTEGER_CST) { - propagate_into_all_uses (result, arg); + replace_uses_by (result, arg); gsi_remove (&gsi, true); release_ssa_name (result); } @@ -1258,7 +1228,7 @@ propagate_constants_for_unrolling (basic_block bb) && (lhs = gimple_assign_lhs (stmt), TREE_CODE (lhs) == SSA_NAME) && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) { - propagate_into_all_uses (lhs, gimple_assign_rhs1 (stmt)); + replace_uses_by (lhs, gimple_assign_rhs1 (stmt)); gsi_remove (&gsi, true); release_ssa_name (lhs); } diff --git a/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c b/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c index fc63825904..8db3a34dca 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c @@ -2489,9 +2489,9 @@ static widest_int derive_constant_upper_bound (tree val) { enum tree_code code; - tree op0, op1; + tree op0, op1, op2; - extract_ops_from_tree (val, &code, &op0, &op1); + extract_ops_from_tree (val, &code, &op0, &op1, &op2); return derive_constant_upper_bound_ops (TREE_TYPE (val), op0, code, op1); } @@ -2504,7 +2504,7 @@ derive_constant_upper_bound_ops (tree type, tree op0, enum tree_code code, tree op1) { tree subtype, maxt; - widest_int bnd, max, mmax, cst; + widest_int bnd, max, cst; gimple stmt; if (INTEGRAL_TYPE_P (type)) @@ -2570,8 +2570,8 @@ derive_constant_upper_bound_ops (tree type, tree op0, /* OP0 + CST. We need to check that BND <= MAX (type) - CST. */ - mmax -= cst; - if (wi::ltu_p (bnd, max)) + widest_int mmax = max - cst; + if (wi::leu_p (bnd, mmax)) return max; return bnd + cst; @@ -2788,7 +2788,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple stmt, && get_range_info (orig_base, &min, &max) == VR_RANGE && wi::gts_p (high, max)) base = wide_int_to_tree (unsigned_type, max); - else if (TREE_CODE (base) != INTEGER_CST) + else if (TREE_CODE (base) != INTEGER_CST + && dominated_by_p (CDI_DOMINATORS, + loop->latch, gimple_bb (stmt))) base = fold_convert (unsigned_type, high); delta = fold_build2 (MINUS_EXPR, unsigned_type, base, extreme); step = fold_build1 (NEGATE_EXPR, unsigned_type, step); @@ -2803,7 +2805,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple stmt, && get_range_info (orig_base, &min, &max) == VR_RANGE && wi::gts_p (min, low)) base = wide_int_to_tree (unsigned_type, min); - else if (TREE_CODE (base) != INTEGER_CST) + else if (TREE_CODE (base) != INTEGER_CST + && dominated_by_p (CDI_DOMINATORS, + loop->latch, gimple_bb (stmt))) base = fold_convert (unsigned_type, low); delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base); } diff --git a/contrib/gcc-5.0/gcc/tree-ssa-loop.c b/contrib/gcc-5.0/gcc/tree-ssa-loop.c index ccb8f9762b..78dae5d8ba 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-loop.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-loop.c @@ -698,6 +698,8 @@ gen_lsm_tmp_name (tree ref) case SSA_NAME: case VAR_DECL: case PARM_DECL: + case FUNCTION_DECL: + case LABEL_DECL: name = get_name (ref); if (!name) name = "D"; @@ -713,11 +715,9 @@ gen_lsm_tmp_name (tree ref) break; case INTEGER_CST: + default: /* Nothing. */ break; - - default: - gcc_unreachable (); } } diff --git a/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c b/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c index c699dcadbe..61b65bb824 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c @@ -769,7 +769,7 @@ execute_cse_sincos_1 (tree name) if (gimple_code (use_stmt) != GIMPLE_CALL || !gimple_call_lhs (use_stmt) || !(fndecl = gimple_call_fndecl (use_stmt)) - || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) + || !gimple_call_builtin_p (use_stmt, BUILT_IN_NORMAL)) continue; switch (DECL_FUNCTION_CODE (fndecl)) @@ -1488,7 +1488,7 @@ pass_cse_sincos::execute (function *fun) if (is_gimple_call (stmt) && gimple_call_lhs (stmt) && (fndecl = gimple_call_fndecl (stmt)) - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) { tree arg, arg0, arg1, result; HOST_WIDE_INT n; @@ -2141,9 +2141,9 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) static gimple find_bswap_or_nop (gimple stmt, struct symbolic_number *n, bool *bswap) { -/* The number which the find_bswap_or_nop_1 result should match in order - to have a full byte swap. The number is shifted to the right - according to the size of the symbolic number before using it. */ + /* The number which the find_bswap_or_nop_1 result should match in order + to have a full byte swap. The number is shifted to the right + according to the size of the symbolic number before using it. */ uint64_t cmpxchg = CMPXCHG; uint64_t cmpnop = CMPNOP; @@ -2165,10 +2165,14 @@ find_bswap_or_nop (gimple stmt, struct symbolic_number *n, bool *bswap) /* Find real size of result (highest non-zero byte). */ if (n->base_addr) { - int rsize; + unsigned HOST_WIDE_INT rsize; uint64_t tmpn; for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER, rsize++); + if (BYTES_BIG_ENDIAN && n->range != rsize) + /* This implies an offset, which is currently not handled by + bswap_replace. */ + return NULL; n->range = rsize; } @@ -2297,6 +2301,8 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type, /* Move cur_stmt just before one of the load of the original to ensure it has the same VUSE. See PR61517 for what could go wrong. */ + if (gimple_bb (cur_stmt) != gimple_bb (src_stmt)) + reset_flow_sensitive_info (gimple_assign_lhs (cur_stmt)); gsi_move_before (&gsi, &gsi_ins); gsi = gsi_for_stmt (cur_stmt); @@ -3333,7 +3339,7 @@ pass_optimize_widening_mul::execute (function *fun) { tree fndecl = gimple_call_fndecl (stmt); if (fndecl - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) { switch (DECL_FUNCTION_CODE (fndecl)) { diff --git a/contrib/gcc-5.0/gcc/tree-ssa-pre.c b/contrib/gcc-5.0/gcc/tree-ssa-pre.c index 805cc21e10..c5c06ca4b1 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-pre.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-pre.c @@ -2112,11 +2112,6 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block) static sbitmap has_abnormal_preds; -/* List of blocks that may have changed during ANTIC computation and - thus need to be iterated over. */ - -static sbitmap changed_blocks; - /* Compute the ANTIC set for BLOCK. If succs(BLOCK) > 1 then @@ -2136,6 +2131,7 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) unsigned int bii; edge e; edge_iterator ei; + bool was_visited = BB_VISITED (block); old = ANTIC_OUT = S = NULL; BB_VISITED (block) = 1; @@ -2175,6 +2171,16 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) first = e->dest; else if (BB_VISITED (e->dest)) worklist.quick_push (e->dest); + else + { + /* Unvisited successors get their ANTIC_IN replaced by the + maximal set to arrive at a maximum ANTIC_IN solution. + We can ignore them in the intersection operation and thus + need not explicitely represent that maximum solution. */ + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "ANTIC_IN is MAX on %d->%d\n", + e->src->index, e->dest->index); + } } /* Of multiple successors we have to have visited one already @@ -2216,15 +2222,8 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) clean (ANTIC_IN (block)); - if (!bitmap_set_equal (old, ANTIC_IN (block))) - { - changed = true; - bitmap_set_bit (changed_blocks, block->index); - FOR_EACH_EDGE (e, ei, block->preds) - bitmap_set_bit (changed_blocks, e->src->index); - } - else - bitmap_clear_bit (changed_blocks, block->index); + if (!was_visited || !bitmap_set_equal (old, ANTIC_IN (block))) + changed = true; maybe_dump_sets: if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2232,6 +2231,8 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) if (ANTIC_OUT) print_bitmap_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index); + if (changed) + fprintf (dump_file, "[changed] "); print_bitmap_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index); @@ -2363,14 +2364,7 @@ compute_partial_antic_aux (basic_block block, dependent_clean (PA_IN (block), ANTIC_IN (block)); if (!bitmap_set_equal (old_PA_IN, PA_IN (block))) - { - changed = true; - bitmap_set_bit (changed_blocks, block->index); - FOR_EACH_EDGE (e, ei, block->preds) - bitmap_set_bit (changed_blocks, e->src->index); - } - else - bitmap_clear_bit (changed_blocks, block->index); + changed = true; maybe_dump_sets: if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2396,6 +2390,8 @@ compute_antic (void) int num_iterations = 0; basic_block block; int i; + edge_iterator ei; + edge e; /* If any predecessor edges are abnormal, we punt, so antic_in is empty. We pre-build the map of blocks with incoming abnormal edges here. */ @@ -2404,20 +2400,17 @@ compute_antic (void) FOR_ALL_BB_FN (block, cfun) { - edge_iterator ei; - edge e; + BB_VISITED (block) = 0; FOR_EACH_EDGE (e, ei, block->preds) - { - e->flags &= ~EDGE_DFS_BACK; - if (e->flags & EDGE_ABNORMAL) - { - bitmap_set_bit (has_abnormal_preds, block->index); - break; - } - } + if (e->flags & EDGE_ABNORMAL) + { + bitmap_set_bit (has_abnormal_preds, block->index); - BB_VISITED (block) = 0; + /* We also anticipate nothing. */ + BB_VISITED (block) = 1; + break; + } /* While we are here, give empty ANTIC_IN sets to each block. */ ANTIC_IN (block) = bitmap_set_new (); @@ -2427,8 +2420,8 @@ compute_antic (void) /* At the exit block we anticipate nothing. */ BB_VISITED (EXIT_BLOCK_PTR_FOR_FN (cfun)) = 1; - changed_blocks = sbitmap_alloc (last_basic_block_for_fn (cfun) + 1); - bitmap_ones (changed_blocks); + sbitmap worklist = sbitmap_alloc (last_basic_block_for_fn (cfun) + 1); + bitmap_ones (worklist); while (changed) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2441,12 +2434,18 @@ compute_antic (void) changed = false; for (i = postorder_num - 1; i >= 0; i--) { - if (bitmap_bit_p (changed_blocks, postorder[i])) + if (bitmap_bit_p (worklist, postorder[i])) { basic_block block = BASIC_BLOCK_FOR_FN (cfun, postorder[i]); - changed |= compute_antic_aux (block, - bitmap_bit_p (has_abnormal_preds, - block->index)); + bitmap_clear_bit (worklist, block->index); + if (compute_antic_aux (block, + bitmap_bit_p (has_abnormal_preds, + block->index))) + { + FOR_EACH_EDGE (e, ei, block->preds) + bitmap_set_bit (worklist, e->src->index); + changed = true; + } } } /* Theoretically possible, but *highly* unlikely. */ @@ -2458,7 +2457,7 @@ compute_antic (void) if (do_partial_partial) { - bitmap_ones (changed_blocks); + bitmap_ones (worklist); mark_dfs_back_edges (); num_iterations = 0; changed = true; @@ -2470,13 +2469,18 @@ compute_antic (void) changed = false; for (i = postorder_num - 1 ; i >= 0; i--) { - if (bitmap_bit_p (changed_blocks, postorder[i])) + if (bitmap_bit_p (worklist, postorder[i])) { basic_block block = BASIC_BLOCK_FOR_FN (cfun, postorder[i]); - changed - |= compute_partial_antic_aux (block, - bitmap_bit_p (has_abnormal_preds, - block->index)); + bitmap_clear_bit (worklist, block->index); + if (compute_partial_antic_aux (block, + bitmap_bit_p (has_abnormal_preds, + block->index))) + { + FOR_EACH_EDGE (e, ei, block->preds) + bitmap_set_bit (worklist, e->src->index); + changed = true; + } } } /* Theoretically possible, but *highly* unlikely. */ @@ -2486,7 +2490,7 @@ compute_antic (void) num_iterations); } sbitmap_free (has_abnormal_preds); - sbitmap_free (changed_blocks); + sbitmap_free (worklist); } @@ -3847,7 +3851,7 @@ compute_avail (void) vn_reference_t ref; vn_reference_lookup (gimple_assign_rhs1 (stmt), gimple_vuse (stmt), - VN_WALK, &ref); + VN_WALK, &ref, true); if (!ref) continue; @@ -4308,7 +4312,7 @@ eliminate_dom_walker::before_dom_children (basic_block b) tree val; tree rhs = gimple_assign_rhs1 (stmt); val = vn_reference_lookup (gimple_assign_lhs (stmt), - gimple_vuse (stmt), VN_WALK, NULL); + gimple_vuse (stmt), VN_WALK, NULL, false); if (TREE_CODE (rhs) == SSA_NAME) rhs = VN_INFO (rhs)->valnum; if (val @@ -4768,12 +4772,14 @@ init_pre (void) connect_infinite_loops_to_exit (); memset (&pre_stats, 0, sizeof (pre_stats)); + /* For ANTIC computation we need a postorder that also guarantees that + a block with a single successor is visited after its successor. + RPO on the inverted CFG has this property. */ postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun)); postorder_num = inverted_post_order_compute (postorder); alloc_aux_for_blocks (sizeof (struct bb_bitmap_sets)); - calculate_dominance_info (CDI_POST_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS); bitmap_obstack_initialize (&grand_bitmap_obstack); @@ -4811,8 +4817,6 @@ fini_pre () name_to_id.release (); free_aux_for_blocks (); - - free_dominance_info (CDI_POST_DOMINATORS); } namespace { diff --git a/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c b/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c index 8f24eed54f..0710bae7de 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c @@ -2134,11 +2134,33 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange, in_p, low, high); enum warn_strict_overflow_code wc = WARN_STRICT_OVERFLOW_COMPARISON; gimple_stmt_iterator gsi; - unsigned int i; + unsigned int i, uid; if (tem == NULL_TREE) return false; + /* If op is default def SSA_NAME, there is no place to insert the + new comparison. Give up, unless we can use OP itself as the + range test. */ + if (op && SSA_NAME_IS_DEFAULT_DEF (op)) + { + if (op == range->exp + && ((TYPE_PRECISION (optype) == 1 && TYPE_UNSIGNED (optype)) + || TREE_CODE (optype) == BOOLEAN_TYPE) + && (op == tem + || (TREE_CODE (tem) == EQ_EXPR + && TREE_OPERAND (tem, 0) == op + && integer_onep (TREE_OPERAND (tem, 1)))) + && opcode != BIT_IOR_EXPR + && (opcode != ERROR_MARK || oe->rank != BIT_IOR_EXPR)) + { + stmt = NULL; + tem = op; + } + else + return false; + } + if (strict_overflow_p && issue_strict_overflow_warning (wc)) warning_at (loc, OPT_Wstrict_overflow, "assuming signed overflow does not occur " @@ -2176,12 +2198,22 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange, tem = invert_truthvalue_loc (loc, tem); tem = fold_convert_loc (loc, optype, tem); - gsi = gsi_for_stmt (stmt); - unsigned int uid = gimple_uid (stmt); + if (stmt) + { + gsi = gsi_for_stmt (stmt); + uid = gimple_uid (stmt); + } + else + { + gsi = gsi_none (); + uid = 0; + } + if (stmt == NULL) + gcc_checking_assert (tem == op); /* In rare cases range->exp can be equal to lhs of stmt. In that case we have to insert after the stmt rather then before it. If stmt is a PHI, insert it at the start of the basic block. */ - if (op != range->exp) + else if (op != range->exp) { gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, true, @@ -3286,7 +3318,7 @@ maybe_optimize_range_tests (gimple stmt) any_changes = optimize_range_tests (ERROR_MARK, &ops); if (any_changes) { - unsigned int idx; + unsigned int idx, max_idx = 0; /* update_ops relies on has_single_use predicates returning the same values as it did during get_ops earlier. Additionally it never removes statements, only adds new ones and it should walk @@ -3302,6 +3334,7 @@ maybe_optimize_range_tests (gimple stmt) { tree new_op; + max_idx = idx; stmt = last_stmt (bb); new_op = update_ops (bbinfo[idx].op, (enum tree_code) @@ -3371,6 +3404,10 @@ maybe_optimize_range_tests (gimple stmt) && ops[bbinfo[idx].first_idx]->op != NULL_TREE) { gcond *cond_stmt = as_a (last_stmt (bb)); + + if (idx > max_idx) + max_idx = idx; + if (integer_zerop (ops[bbinfo[idx].first_idx]->op)) gimple_cond_make_false (cond_stmt); else if (integer_onep (ops[bbinfo[idx].first_idx]->op)) @@ -3387,6 +3424,17 @@ maybe_optimize_range_tests (gimple stmt) if (bb == first_bb) break; } + + /* The above changes could result in basic blocks after the first + modified one, up to and including last_bb, to be executed even if + they would not be in the original program. If the value ranges of + assignment lhs' in those bbs were dependent on the conditions + guarding those basic blocks which now can change, the VRs might + be incorrect. As no_side_effect_bb should ensure those SSA_NAMEs + are only used within the same bb, it should be not a big deal if + we just reset all the VRs in those bbs. See PR68671. */ + for (bb = last_bb, idx = 0; idx < max_idx; bb = single_pred (bb), idx++) + reset_flow_sensitive_info_in_bb (bb); } } diff --git a/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c b/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c index a99a28fc68..db554d6fea 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c @@ -2199,11 +2199,12 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, tree type, number if it exists in the hash table. Return NULL_TREE if it does not exist in the hash table or if the result field of the structure was NULL.. VNRESULT will be filled in with the vn_reference_t - stored in the hashtable if one exists. */ + stored in the hashtable if one exists. When TBAA_P is false assume + we are looking up a store and treat it as having alias-set zero. */ tree vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind, - vn_reference_t *vnresult) + vn_reference_t *vnresult, bool tbaa_p) { vec operands; struct vn_reference_s vr1; @@ -2217,7 +2218,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind, vr1.operands = operands = valueize_shared_reference_ops_from_ref (op, &valuezied_anything); vr1.type = TREE_TYPE (op); - vr1.set = get_alias_set (op); + vr1.set = tbaa_p ? get_alias_set (op) : 0; vr1.hashcode = vn_reference_compute_hash (&vr1); if ((cst = fully_constant_vn_reference_p (&vr1))) return cst; @@ -2233,6 +2234,8 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind, || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type, vr1.operands)) ao_ref_init (&r, op); + if (! tbaa_p) + r.ref_alias_set = r.base_alias_set = 0; vn_walk_kind = kind; wvnresult = (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, @@ -3030,7 +3033,7 @@ visit_reference_op_load (tree lhs, tree op, gimple stmt) last_vuse = gimple_vuse (stmt); last_vuse_ptr = &last_vuse; result = vn_reference_lookup (op, gimple_vuse (stmt), - default_vn_walk_kind, NULL); + default_vn_walk_kind, NULL, true); last_vuse_ptr = NULL; /* We handle type-punning through unions by value-numbering based @@ -3149,7 +3152,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt) Otherwise, the vdefs for the store are used when inserting into the table, since the store generates a new memory state. */ - result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL); + result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL, false); if (result) { @@ -3164,7 +3167,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt) && default_vn_walk_kind == VN_WALK) { assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op); - vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult); + vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false); if (vnresult) { VN_INFO (vdef)->use_processed = true; diff --git a/contrib/gcc-5.0/gcc/tree-ssa-sccvn.h b/contrib/gcc-5.0/gcc/tree-ssa-sccvn.h index 717fc288d8..36c6b8179c 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-sccvn.h +++ b/contrib/gcc-5.0/gcc/tree-ssa-sccvn.h @@ -211,7 +211,7 @@ bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree, tree vn_reference_lookup_pieces (tree, alias_set_type, tree, vec , vn_reference_t *, vn_lookup_kind); -tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *); +tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *, bool); void vn_reference_lookup_call (gcall *, vn_reference_t *, vn_reference_t); vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree, vec , diff --git a/contrib/gcc-5.0/gcc/tree-ssa-strlen.c b/contrib/gcc-5.0/gcc/tree-ssa-strlen.c index 34776a38c3..e6eaad43a9 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-strlen.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-strlen.c @@ -916,6 +916,65 @@ find_equal_ptrs (tree ptr, int idx) } } +/* Return true if STMT is a call to a builtin function with the right + arguments and attributes that should be considered for optimization + by this pass. */ + +static bool +valid_builtin_call (gimple stmt) +{ + if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) + return false; + + tree callee = gimple_call_fndecl (stmt); + switch (DECL_FUNCTION_CODE (callee)) + { + case BUILT_IN_MEMCMP: + case BUILT_IN_STRCHR: + case BUILT_IN_STRCHR_CHKP: + case BUILT_IN_STRLEN: + case BUILT_IN_STRLEN_CHKP: + /* The above functions should be pure. Punt if they aren't. */ + if (gimple_vdef (stmt) || gimple_vuse (stmt) == NULL_TREE) + return false; + break; + + case BUILT_IN_CALLOC: + case BUILT_IN_MALLOC: + case BUILT_IN_MEMCPY: + case BUILT_IN_MEMCPY_CHK: + case BUILT_IN_MEMCPY_CHKP: + case BUILT_IN_MEMCPY_CHK_CHKP: + case BUILT_IN_MEMPCPY: + case BUILT_IN_MEMPCPY_CHK: + case BUILT_IN_MEMPCPY_CHKP: + case BUILT_IN_MEMPCPY_CHK_CHKP: + case BUILT_IN_MEMSET: + case BUILT_IN_STPCPY: + case BUILT_IN_STPCPY_CHK: + case BUILT_IN_STPCPY_CHKP: + case BUILT_IN_STPCPY_CHK_CHKP: + case BUILT_IN_STRCAT: + case BUILT_IN_STRCAT_CHK: + case BUILT_IN_STRCAT_CHKP: + case BUILT_IN_STRCAT_CHK_CHKP: + case BUILT_IN_STRCPY: + case BUILT_IN_STRCPY_CHK: + case BUILT_IN_STRCPY_CHKP: + case BUILT_IN_STRCPY_CHK_CHKP: + /* The above functions should be neither const nor pure. Punt if they + aren't. */ + if (gimple_vdef (stmt) == NULL_TREE || gimple_vuse (stmt) == NULL_TREE) + return false; + break; + + default: + break; + } + + return true; +} + /* If the last .MEM setter statement before STMT is memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to @@ -991,7 +1050,7 @@ adjust_last_stmt (strinfo si, gimple stmt, bool is_strcat) return; } - if (!gimple_call_builtin_p (last.stmt, BUILT_IN_NORMAL)) + if (!valid_builtin_call (last.stmt)) return; callee = gimple_call_fndecl (last.stmt); @@ -1867,7 +1926,7 @@ handle_builtin_memset (gimple_stmt_iterator *gsi) if (!stmt1 || !is_gimple_call (stmt1)) return true; tree callee1 = gimple_call_fndecl (stmt1); - if (!gimple_call_builtin_p (stmt1, BUILT_IN_NORMAL)) + if (!valid_builtin_call (stmt1)) return true; enum built_in_function code1 = DECL_FUNCTION_CODE (callee1); tree size = gimple_call_arg (stmt2, 2); @@ -2112,7 +2171,7 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi) if (is_gimple_call (stmt)) { tree callee = gimple_call_fndecl (stmt); - if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) + if (valid_builtin_call (stmt)) switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_STRLEN: diff --git a/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c b/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c index 610e80792d..72fc5f897a 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c @@ -254,6 +254,11 @@ struct ssa_local_info_t /* Blocks duplicated for the thread. */ bitmap duplicate_blocks; + + /* When we have multiple paths through a joiner which reach different + final destinations, then we may need to correct for potential + profile insanities. */ + bool need_profile_correction; }; /* Passes which use the jump threading code register jump threading @@ -827,7 +832,8 @@ compute_path_counts (struct redirection_data *rd, So ensure that this path's path_out_count is at least the difference between elast->count and nonpath_count. Otherwise the edge counts after threading will not be sane. */ - if (has_joiner && path_out_count < elast->count - nonpath_count) + if (local_info->need_profile_correction + && has_joiner && path_out_count < elast->count - nonpath_count) { path_out_count = elast->count - nonpath_count; /* But neither can we go above the minimum count along the path @@ -1496,6 +1502,7 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) ssa_local_info_t local_info; local_info.duplicate_blocks = BITMAP_ALLOC (NULL); + local_info.need_profile_correction = false; /* To avoid scanning a linear array for the element we need we instead use a hash table. For normal code there should be no noticeable @@ -1506,6 +1513,7 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) /* Record each unique threaded destination into a hash table for efficient lookups. */ + edge last = NULL; FOR_EACH_EDGE (e, ei, bb->preds) { if (e->aux == NULL) @@ -1559,6 +1567,17 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) /* Insert the outgoing edge into the hash table if it is not already in the hash table. */ lookup_redirection_data (e, INSERT); + + /* When we have thread paths through a common joiner with different + final destinations, then we may need corrections to deal with + profile insanities. See the big comment before compute_path_counts. */ + if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK) + { + if (!last) + last = e2; + else if (e2 != last) + local_info.need_profile_correction = true; + } } /* We do not update dominance info. */ diff --git a/contrib/gcc-5.0/gcc/tree-ssa-uninit.c b/contrib/gcc-5.0/gcc/tree-ssa-uninit.c index fb2f3b3185..2d9ac297db 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-uninit.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-uninit.c @@ -159,6 +159,31 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var, if (!has_undefined_value_p (t)) return; + /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p + can return true if the def stmt of anonymous SSA_NAME is COMPLEX_EXPR + created for conversion from scalar to complex. Use the underlying var of + the COMPLEX_EXPRs real part in that case. See PR71581. */ + if (expr == NULL_TREE + && var == NULL_TREE + && SSA_NAME_VAR (t) == NULL_TREE + && is_gimple_assign (SSA_NAME_DEF_STMT (t)) + && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (t)) == COMPLEX_EXPR) + { + tree v = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (t)); + if (TREE_CODE (v) == SSA_NAME + && has_undefined_value_p (v) + && (integer_zerop (gimple_assign_rhs2 (SSA_NAME_DEF_STMT (t))) + || real_zerop (gimple_assign_rhs2 (SSA_NAME_DEF_STMT (t))) + || fixed_zerop (gimple_assign_rhs2 (SSA_NAME_DEF_STMT (t))))) + { + expr = SSA_NAME_VAR (v); + var = expr; + } + } + + if (expr == NULL_TREE) + return; + /* TREE_NO_WARNING either means we already warned, or the front end wishes to suppress the warning. */ if ((context @@ -1118,14 +1143,16 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi, edge opnd_edge; unsigned uninit_opnds2 = compute_uninit_opnds_pos (opnd_def_phi); - gcc_assert (!MASK_EMPTY (uninit_opnds2)); - opnd_edge = gimple_phi_arg_edge (phi, i); - if (!is_use_properly_guarded (phi, - opnd_edge->src, - opnd_def_phi, - uninit_opnds2, - visited_phis)) - return false; + if (!MASK_EMPTY (uninit_opnds2)) + { + opnd_edge = gimple_phi_arg_edge (phi, i); + if (!is_use_properly_guarded (phi, + opnd_edge->src, + opnd_def_phi, + uninit_opnds2, + visited_phis)) + return false; + } } else return false; diff --git a/contrib/gcc-5.0/gcc/tree-ssa.c b/contrib/gcc-5.0/gcc/tree-ssa.c index 10d3314558..a3c0c0d815 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa.c +++ b/contrib/gcc-5.0/gcc/tree-ssa.c @@ -1354,6 +1354,18 @@ non_rewritable_lvalue_p (tree lhs) tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0); if (DECL_P (decl) && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs)) + /* If the dynamic type of the decl has larger precision than + the decl itself we can't use the decls type for SSA rewriting. */ + && ((! INTEGRAL_TYPE_P (TREE_TYPE (decl)) + || compare_tree_int (DECL_SIZE (decl), + TYPE_PRECISION (TREE_TYPE (decl))) == 0) + || (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) + && (TYPE_PRECISION (TREE_TYPE (decl)) + >= TYPE_PRECISION (TREE_TYPE (lhs))))) + /* Make sure we are not re-writing non-float copying into float + copying as that can incur normalization. */ + && (! FLOAT_TYPE_P (TREE_TYPE (decl)) + || types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (decl))) && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs))) return false; } @@ -1448,7 +1460,8 @@ execute_update_addresses_taken (void) tree lhs = gimple_get_lhs (stmt); if (lhs && TREE_CODE (lhs) != SSA_NAME - && non_rewritable_lvalue_p (lhs)) + && ((code == GIMPLE_CALL && ! DECL_P (lhs)) + || non_rewritable_lvalue_p (lhs))) { decl = get_base_address (lhs); if (DECL_P (decl)) diff --git a/contrib/gcc-5.0/gcc/tree-vect-data-refs.c b/contrib/gcc-5.0/gcc/tree-vect-data-refs.c index 8085d20752..76a9fd71ad 100644 --- a/contrib/gcc-5.0/gcc/tree-vect-data-refs.c +++ b/contrib/gcc-5.0/gcc/tree-vect-data-refs.c @@ -2593,7 +2593,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) /* Sorting has ensured that DR_INIT (dra) <= DR_INIT (drb). */ HOST_WIDE_INT init_a = TREE_INT_CST_LOW (DR_INIT (dra)); HOST_WIDE_INT init_b = TREE_INT_CST_LOW (DR_INIT (drb)); - gcc_assert (init_a < init_b); + gcc_assert (init_a <= init_b); /* If init_b == init_a + the size of the type * k, we have an interleaving, and DRA is accessed before DRB. */ @@ -2905,10 +2905,38 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) || !tree_fits_shwi_p (dr_a2->offset)) continue; - HOST_WIDE_INT diff = (tree_to_shwi (dr_a2->offset) - - tree_to_shwi (dr_a1->offset)); + /* Make sure dr_a1 starts left of dr_a2. */ + if (tree_int_cst_lt (dr_a2->offset, dr_a1->offset)) + std::swap (*dr_a1, *dr_a2); + unsigned HOST_WIDE_INT diff + = tree_to_shwi (dr_a2->offset) - tree_to_shwi (dr_a1->offset); + + bool do_remove = false; + + /* If the left segment does not extend beyond the start of the + right segment the new segment length is that of the right + plus the segment distance. */ + if (tree_fits_uhwi_p (dr_a1->seg_len) + && compare_tree_int (dr_a1->seg_len, diff) <= 0) + { + dr_a1->seg_len = size_binop (PLUS_EXPR, dr_a2->seg_len, + size_int (diff)); + do_remove = true; + } + /* Generally the new segment length is the maximum of the + left segment size and the right segment size plus the distance. + ??? We can also build tree MAX_EXPR here but it's not clear this + is profitable. */ + else if (tree_fits_uhwi_p (dr_a1->seg_len) + && tree_fits_uhwi_p (dr_a2->seg_len)) + { + unsigned HOST_WIDE_INT seg_len_a1 = tree_to_uhwi (dr_a1->seg_len); + unsigned HOST_WIDE_INT seg_len_a2 = tree_to_uhwi (dr_a2->seg_len); + dr_a1->seg_len = size_int (MAX (seg_len_a1, diff + seg_len_a2)); + do_remove = true; + } /* Now we check if the following condition is satisfied: DIFF - SEGMENT_LENGTH_A < SEGMENT_LENGTH_B @@ -2921,38 +2949,39 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) one above: 1: DIFF <= MIN_SEG_LEN_B - 2: DIFF - SEGMENT_LENGTH_A < MIN_SEG_LEN_B - - */ - - HOST_WIDE_INT min_seg_len_b = (tree_fits_shwi_p (dr_b1->seg_len) - ? tree_to_shwi (dr_b1->seg_len) - : vect_factor); + 2: DIFF - SEGMENT_LENGTH_A < MIN_SEG_LEN_B */ + else + { + unsigned HOST_WIDE_INT min_seg_len_b + = (tree_fits_uhwi_p (dr_b1->seg_len) + ? tree_to_uhwi (dr_b1->seg_len) + : vect_factor); + + if (diff <= min_seg_len_b + || (tree_fits_uhwi_p (dr_a1->seg_len) + && diff - tree_to_uhwi (dr_a1->seg_len) < min_seg_len_b)) + { + dr_a1->seg_len = size_binop (PLUS_EXPR, + dr_a2->seg_len, size_int (diff)); + do_remove = true; + } + } - if (diff <= min_seg_len_b - || (tree_fits_shwi_p (dr_a1->seg_len) - && diff - tree_to_shwi (dr_a1->seg_len) < min_seg_len_b)) + if (do_remove) { if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, "merging ranges for "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, - DR_REF (dr_a1->dr)); + dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_a1->dr)); dump_printf (MSG_NOTE, ", "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, - DR_REF (dr_b1->dr)); + dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_b1->dr)); dump_printf (MSG_NOTE, " and "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, - DR_REF (dr_a2->dr)); + dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_a2->dr)); dump_printf (MSG_NOTE, ", "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, - DR_REF (dr_b2->dr)); + dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_b2->dr)); dump_printf (MSG_NOTE, "\n"); } - - dr_a1->seg_len = size_binop (PLUS_EXPR, - dr_a2->seg_len, size_int (diff)); comp_alias_ddrs.ordered_remove (i--); } } diff --git a/contrib/gcc-5.0/gcc/tree-vect-loop.c b/contrib/gcc-5.0/gcc/tree-vect-loop.c index 05515b522b..fac1d39b28 100644 --- a/contrib/gcc-5.0/gcc/tree-vect-loop.c +++ b/contrib/gcc-5.0/gcc/tree-vect-loop.c @@ -3791,6 +3791,15 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, else init_value = init_val; + /* In case of a nested reduction do not use an adjustment def as + that case is not supported by the epilogue generation correctly + if ncopies is not one. */ + if (adjustment_def && nested_in_vect_loop) + { + *adjustment_def = NULL; + return vect_get_vec_def_for_operand (init_val, stmt, NULL); + } + switch (code) { case WIDEN_SUM_EXPR: @@ -3805,13 +3814,7 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, /* ADJUSMENT_DEF is NULL when called from vect_create_epilog_for_reduction to vectorize double reduction. */ if (adjustment_def) - { - if (nested_in_vect_loop) - *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt, - NULL); - else - *adjustment_def = init_val; - } + *adjustment_def = init_val; if (code == MULT_EXPR) { @@ -4035,17 +4038,25 @@ vect_create_epilog_for_reduction (vec vect_defs, gimple stmt, (in case of SLP, do it for all the phis). */ /* Get the loop-entry arguments. */ + enum vect_def_type initial_def_dt = vect_unknown_def_type; if (slp_node) vect_get_vec_defs (reduction_op, NULL_TREE, stmt, &vec_initial_defs, NULL, slp_node, reduc_index); else { - vec_initial_defs.create (1); + /* Get at the scalar def before the loop, that defines the initial value + of the reduction variable. */ + gimple def_stmt = SSA_NAME_DEF_STMT (reduction_op); + tree initial_def = PHI_ARG_DEF_FROM_EDGE (def_stmt, + loop_preheader_edge (loop)); + vect_is_simple_use (initial_def, NULL, loop_vinfo, NULL, + &def_stmt, &initial_def, &initial_def_dt); /* For the case of reduction, vect_get_vec_def_for_operand returns the scalar def before the loop, that defines the initial value of the reduction variable. */ vec_initial_def = vect_get_vec_def_for_operand (reduction_op, stmt, &adjustment_def); + vec_initial_defs.create (1); vec_initial_defs.quick_push (vec_initial_def); } @@ -4060,6 +4071,15 @@ vect_create_epilog_for_reduction (vec vect_defs, gimple stmt, def = vect_defs[i]; for (j = 0; j < ncopies; j++) { + if (j != 0) + { + phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi)); + if (nested_in_vect_loop) + vec_init_def + = vect_get_vec_def_for_stmt_copy (initial_def_dt, + vec_init_def); + } + /* Set the loop-entry arg of the reduction-phi. */ add_phi_arg (as_a (phi), vec_init_def, loop_preheader_edge (loop), UNKNOWN_LOCATION); @@ -4080,8 +4100,6 @@ vect_create_epilog_for_reduction (vec vect_defs, gimple stmt, dump_gimple_stmt (MSG_NOTE, TDF_SLIM, SSA_NAME_DEF_STMT (def), 0); dump_printf (MSG_NOTE, "\n"); } - - phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi)); } } diff --git a/contrib/gcc-5.0/gcc/tree-vrp.c b/contrib/gcc-5.0/gcc/tree-vrp.c index d5db8759cb..4c132834dd 100644 --- a/contrib/gcc-5.0/gcc/tree-vrp.c +++ b/contrib/gcc-5.0/gcc/tree-vrp.c @@ -9534,7 +9534,8 @@ simplify_cond_using_ranges (gcond *stmt) innerop = gimple_assign_rhs1 (def_stmt); if (TREE_CODE (innerop) == SSA_NAME - && !POINTER_TYPE_P (TREE_TYPE (innerop))) + && !POINTER_TYPE_P (TREE_TYPE (innerop)) + && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)) { value_range_t *vr = get_value_range (innerop); @@ -9565,8 +9566,8 @@ simplify_cond_using_ranges (gcond *stmt) else location = gimple_location (stmt); warning_at (location, OPT_Wstrict_overflow, - "assuming signed overflow does not occur when " - "simplifying conditional"); + "assuming signed overflow does not occur when " + "simplifying conditional"); } tree newconst = fold_convert (TREE_TYPE (innerop), op1); diff --git a/contrib/gcc-5.0/gcc/tree.c b/contrib/gcc-5.0/gcc/tree.c index 6f07d3d951..665143716b 100644 --- a/contrib/gcc-5.0/gcc/tree.c +++ b/contrib/gcc-5.0/gcc/tree.c @@ -1221,11 +1221,9 @@ static unsigned int get_int_cst_ext_nunits (tree type, const wide_int &cst) { gcc_checking_assert (cst.get_precision () == TYPE_PRECISION (type)); - /* We need an extra zero HWI if CST is an unsigned integer with its - upper bit set, and if CST occupies a whole number of HWIs. */ - if (TYPE_UNSIGNED (type) - && wi::neg_p (cst) - && (cst.get_precision () % HOST_BITS_PER_WIDE_INT) == 0) + /* We need extra HWIs if CST is an unsigned integer with its + upper bit set. */ + if (TYPE_UNSIGNED (type) && wi::neg_p (cst)) return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1; return cst.get_len (); } @@ -1242,7 +1240,8 @@ build_new_int_cst (tree type, const wide_int &cst) if (len < ext_len) { --ext_len; - TREE_INT_CST_ELT (nt, ext_len) = 0; + TREE_INT_CST_ELT (nt, ext_len) + = zext_hwi (-1, cst.get_precision () % HOST_BITS_PER_WIDE_INT); for (unsigned int i = len; i < ext_len; ++i) TREE_INT_CST_ELT (nt, i) = -1; } diff --git a/contrib/gcc-5.0/gcc/ubsan.c b/contrib/gcc-5.0/gcc/ubsan.c index 96536c5088..c56864d54e 100644 --- a/contrib/gcc-5.0/gcc/ubsan.c +++ b/contrib/gcc-5.0/gcc/ubsan.c @@ -1611,6 +1611,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg) fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0); else { + initialize_sanitizer_builtins (); /* Create the __ubsan_handle_float_cast_overflow fn call. */ tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0, NULL, ubsan_type_descriptor (expr_type), diff --git a/contrib/gcc-5.0/gcc/var-tracking.c b/contrib/gcc-5.0/gcc/var-tracking.c index 18eff20355..61289482fc 100644 --- a/contrib/gcc-5.0/gcc/var-tracking.c +++ b/contrib/gcc-5.0/gcc/var-tracking.c @@ -5833,11 +5833,6 @@ reverse_op (rtx val, const_rtx expr, rtx_insn *insn) return; } ret = simplify_gen_binary (code, GET_MODE (val), val, arg); - if (ret == val) - /* Ensure ret isn't VALUE itself (which can happen e.g. for - (plus (reg1) (reg2)) when reg2 is known to be 0), as that - breaks a lot of routines during var-tracking. */ - ret = gen_rtx_fmt_ee (PLUS, GET_MODE (val), val, const0_rtx); break; default: gcc_unreachable (); diff --git a/contrib/gcc-5.0/gcc/varasm.c b/contrib/gcc-5.0/gcc/varasm.c index 89151ac7f0..1747605310 100644 --- a/contrib/gcc-5.0/gcc/varasm.c +++ b/contrib/gcc-5.0/gcc/varasm.c @@ -1434,6 +1434,9 @@ make_decl_rtl (tree decl) specifications. */ SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE); DECL_HARD_REGISTER (decl) = 0; + /* Also avoid SSA inconsistencies by pretending this is an external + decl now. */ + DECL_EXTERNAL (decl) = 1; return; } /* Now handle ordinary static variables and functions (in memory). @@ -4944,6 +4947,14 @@ output_constructor_regular_field (oc_local_state *local) unsigned int align2; + /* Output any buffered-up bit-fields preceding this element. */ + if (local->byte_buffer_in_use) + { + assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1); + local->total_bytes++; + local->byte_buffer_in_use = false; + } + if (local->index != NULL_TREE) { /* Perform the index calculation in modulo arithmetic but @@ -4960,22 +4971,19 @@ output_constructor_regular_field (oc_local_state *local) else fieldpos = 0; - /* Output any buffered-up bit-fields preceding this element. */ - if (local->byte_buffer_in_use) - { - assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1); - local->total_bytes++; - local->byte_buffer_in_use = false; - } - /* Advance to offset of this element. Note no alignment needed in an array, since that is guaranteed if each element has the proper size. */ - if ((local->field != NULL_TREE || local->index != NULL_TREE) - && fieldpos > local->total_bytes) + if (local->field != NULL_TREE || local->index != NULL_TREE) { - assemble_zeros (fieldpos - local->total_bytes); - local->total_bytes = fieldpos; + if (fieldpos > local->total_bytes) + { + assemble_zeros (fieldpos - local->total_bytes); + local->total_bytes = fieldpos; + } + else + /* Must not go backwards. */ + gcc_assert (fieldpos == local->total_bytes); } /* Find the alignment of this element. */ diff --git a/contrib/gcc-5.0/gcc/wide-int.cc b/contrib/gcc-5.0/gcc/wide-int.cc index 4e02d2fd9c..00382934bf 100644 --- a/contrib/gcc-5.0/gcc/wide-int.cc +++ b/contrib/gcc-5.0/gcc/wide-int.cc @@ -1225,30 +1225,32 @@ wi_unpack (unsigned HOST_HALF_WIDE_INT *result, const HOST_WIDE_INT *input, result[j++] = mask; } -/* The inverse of wi_unpack. IN_LEN is the the number of input - blocks. The number of output blocks will be half this amount. */ -static void -wi_pack (unsigned HOST_WIDE_INT *result, +/* The inverse of wi_unpack. IN_LEN is the number of input + blocks and PRECISION is the precision of the result. Return the + number of blocks in the canonicalized result. */ +static unsigned int +wi_pack (HOST_WIDE_INT *result, const unsigned HOST_HALF_WIDE_INT *input, - unsigned int in_len) + unsigned int in_len, unsigned int precision) { unsigned int i = 0; unsigned int j = 0; + unsigned int blocks_needed = BLOCKS_NEEDED (precision); - while (i + 2 < in_len) + while (i + 1 < in_len) { - result[j++] = (unsigned HOST_WIDE_INT)input[i] - | ((unsigned HOST_WIDE_INT)input[i + 1] - << HOST_BITS_PER_HALF_WIDE_INT); + result[j++] = ((unsigned HOST_WIDE_INT) input[i] + | ((unsigned HOST_WIDE_INT) input[i + 1] + << HOST_BITS_PER_HALF_WIDE_INT)); i += 2; } /* Handle the case where in_len is odd. For this we zero extend. */ if (in_len & 1) - result[j++] = (unsigned HOST_WIDE_INT)input[i]; - else - result[j++] = (unsigned HOST_WIDE_INT)input[i] - | ((unsigned HOST_WIDE_INT)input[i + 1] << HOST_BITS_PER_HALF_WIDE_INT); + result[j++] = (unsigned HOST_WIDE_INT) input[i]; + else if (j < blocks_needed) + result[j++] = 0; + return canonize (result, j, precision); } /* Multiply Op1 by Op2. If HIGH is set, only the upper half of the @@ -1471,19 +1473,8 @@ wi::mul_internal (HOST_WIDE_INT *val, const HOST_WIDE_INT *op1val, *overflow = true; } - if (high) - { - /* compute [prec] <- ([prec] * [prec]) >> [prec] */ - wi_pack ((unsigned HOST_WIDE_INT *) val, - &r[half_blocks_needed], half_blocks_needed); - return canonize (val, blocks_needed, prec); - } - else - { - /* compute [prec] <- ([prec] * [prec]) && ((1 << [prec]) - 1) */ - wi_pack ((unsigned HOST_WIDE_INT *) val, r, half_blocks_needed); - return canonize (val, blocks_needed, prec); - } + int r_offset = high ? half_blocks_needed : 0; + return wi_pack (val, &r[r_offset], half_blocks_needed, prec); } /* Compute the population count of X. */ @@ -1808,15 +1799,32 @@ wi::divmod_internal (HOST_WIDE_INT *quotient, unsigned int *remainder_len, { unsigned HOST_WIDE_INT o0 = dividend.to_uhwi (); unsigned HOST_WIDE_INT o1 = divisor.to_uhwi (); + unsigned int quotient_len = 1; if (quotient) - quotient[0] = o0 / o1; + { + quotient[0] = o0 / o1; + if (o1 == 1 + && (HOST_WIDE_INT) o0 < 0 + && dividend_prec > HOST_BITS_PER_WIDE_INT) + { + quotient[1] = 0; + quotient_len = 2; + } + } if (remainder) { remainder[0] = o0 % o1; - *remainder_len = 1; + if ((HOST_WIDE_INT) remainder[0] < 0 + && dividend_prec > HOST_BITS_PER_WIDE_INT) + { + remainder[1] = 0; + *remainder_len = 2; + } + else + *remainder_len = 1; } - return 1; + return quotient_len; } /* Make the divisor and dividend positive and remember what we @@ -1858,8 +1866,7 @@ wi::divmod_internal (HOST_WIDE_INT *quotient, unsigned int *remainder_len, unsigned int quotient_len = 0; if (quotient) { - wi_pack ((unsigned HOST_WIDE_INT *) quotient, b_quotient, m); - quotient_len = canonize (quotient, (m + 1) / 2, dividend_prec); + quotient_len = wi_pack (quotient, b_quotient, m, dividend_prec); /* The quotient is neg if exactly one of the divisor or dividend is neg. */ if (dividend_neg != divisor_neg) @@ -1870,8 +1877,7 @@ wi::divmod_internal (HOST_WIDE_INT *quotient, unsigned int *remainder_len, if (remainder) { - wi_pack ((unsigned HOST_WIDE_INT *) remainder, b_remainder, n); - *remainder_len = canonize (remainder, (n + 1) / 2, dividend_prec); + *remainder_len = wi_pack (remainder, b_remainder, n, dividend_prec); /* The remainder is always the same sign as the dividend. */ if (dividend_neg) *remainder_len = wi::sub_large (remainder, zeros, 1, remainder, diff --git a/contrib/gcc-5.0/gcc/wide-int.h b/contrib/gcc-5.0/gcc/wide-int.h index 9a71c4fea6..18b5e2038f 100644 --- a/contrib/gcc-5.0/gcc/wide-int.h +++ b/contrib/gcc-5.0/gcc/wide-int.h @@ -2892,7 +2892,9 @@ wi::lrshift (const T1 &x, const T2 &y) For variable-precision integers like wide_int, handle HWI and sub-HWI integers inline. */ if (STATIC_CONSTANT_P (xi.precision > HOST_BITS_PER_WIDE_INT) - ? xi.len == 1 && xi.val[0] >= 0 + ? (shift < HOST_BITS_PER_WIDE_INT + && xi.len == 1 + && xi.val[0] >= 0) : xi.precision <= HOST_BITS_PER_WIDE_INT) { val[0] = xi.to_uhwi () >> shift; diff --git a/contrib/gcc-5.0/include/demangle.h b/contrib/gcc-5.0/include/demangle.h index d2a6731a9e..7fa7557b2c 100644 --- a/contrib/gcc-5.0/include/demangle.h +++ b/contrib/gcc-5.0/include/demangle.h @@ -380,6 +380,10 @@ enum demangle_component_type /* A typecast, represented as a unary operator. The one subtree is the type to which the argument should be cast. */ DEMANGLE_COMPONENT_CAST, + /* A conversion operator, represented as a unary operator. The one + subtree is the type to which the argument should be converted + to. */ + DEMANGLE_COMPONENT_CONVERSION, /* A nullary expression. The left subtree is the operator. */ DEMANGLE_COMPONENT_NULLARY, /* A unary expression. The left subtree is the operator, and the diff --git a/contrib/gcc-5.0/libbacktrace/elf.c b/contrib/gcc-5.0/libbacktrace/elf.c index 3f14b11a43..7a8fd5477b 100644 --- a/contrib/gcc-5.0/libbacktrace/elf.c +++ b/contrib/gcc-5.0/libbacktrace/elf.c @@ -867,6 +867,9 @@ struct phdr_data libraries. */ static int +#ifdef __i386__ +__attribute__ ((__force_align_arg_pointer__)) +#endif phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED, void *pdata) { diff --git a/contrib/gcc-5.0/libcpp/files.c b/contrib/gcc-5.0/libcpp/files.c index 9f28b9ef1e..ea2cc23d62 100644 --- a/contrib/gcc-5.0/libcpp/files.c +++ b/contrib/gcc-5.0/libcpp/files.c @@ -522,7 +522,10 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, return entry->u.file; file = make_cpp_file (pfile, start_dir, fname); - file->implicit_preinclude = implicit_preinclude; + file->implicit_preinclude + = (implicit_preinclude + || (pfile->buffer + && pfile->buffer->file->implicit_preinclude)); /* Try each path in the include chain. */ for (; !fake ;) diff --git a/contrib/gcc-5.0/libcpp/include/cpplib.h b/contrib/gcc-5.0/libcpp/include/cpplib.h index 2d90ccd0e8..1b731d1a3a 100644 --- a/contrib/gcc-5.0/libcpp/include/cpplib.h +++ b/contrib/gcc-5.0/libcpp/include/cpplib.h @@ -804,6 +804,7 @@ extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, extern const cpp_token *cpp_get_token (cpp_reader *); extern const cpp_token *cpp_get_token_with_location (cpp_reader *, source_location *); +extern bool cpp_fun_like_macro_p (cpp_hashnode *); extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *); extern void _cpp_backup_tokens (cpp_reader *, unsigned int); diff --git a/contrib/gcc-5.0/libcpp/line-map.c b/contrib/gcc-5.0/libcpp/line-map.c index f9260d0000..340eabac7f 100644 --- a/contrib/gcc-5.0/libcpp/line-map.c +++ b/contrib/gcc-5.0/libcpp/line-map.c @@ -218,7 +218,7 @@ new_linemap (struct line_maps *set, if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p)) { /* We ran out of allocated line maps. Let's allocate more. */ - unsigned alloc_size; + size_t alloc_size; /* Cast away extern "C" from the type of xrealloc. */ line_map_realloc reallocator = (set->reallocator diff --git a/contrib/gcc-5.0/libcpp/macro.c b/contrib/gcc-5.0/libcpp/macro.c index 1e0a0b560b..eb32a6f8c9 100644 --- a/contrib/gcc-5.0/libcpp/macro.c +++ b/contrib/gcc-5.0/libcpp/macro.c @@ -3307,6 +3307,15 @@ check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, } } +/* Returns true of NODE is a function-like macro. */ +bool +cpp_fun_like_macro_p (cpp_hashnode *node) +{ + return (node->type == NT_MACRO + && (node->flags & (NODE_BUILTIN | NODE_MACRO_ARG)) == 0 + && node->value.macro->fun_like); +} + /* Returns the name, arguments and expansion of a macro, in a format suitable to be read back in again, and therefore also for DWARF 2 debugging info. e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION". diff --git a/contrib/gcc-5.0/libgcc/config.host b/contrib/gcc-5.0/libgcc/config.host index 4329891fb9..b4b0665d4b 100644 --- a/contrib/gcc-5.0/libgcc/config.host +++ b/contrib/gcc-5.0/libgcc/config.host @@ -913,14 +913,9 @@ mmix-knuth-mmixware) mn10300-*-*) tmake_file=t-fdpbit ;; -moxie-*-elf | moxie-*-moxiebox* | moxie-*-uclinux*) - tmake_file="moxie/t-moxie t-softfp-sfdf t-softfp-excl t-softfp" - extra_parts="$extra_parts crti.o crtn.o crtbegin.o crtend.o" - ;; -moxie-*-rtems*) +moxie-*-elf | moxie-*-moxiebox* | moxie-*-uclinux* | moxie-*-rtems*) tmake_file="$tmake_file moxie/t-moxie t-softfp-sfdf t-softfp-excl t-softfp" - # Don't use default. - extra_parts= + extra_parts="$extra_parts crti.o crtn.o crtbegin.o crtend.o" ;; msp430*-*-elf) tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430" diff --git a/contrib/gcc-5.0/libgcc/libgcc2.c b/contrib/gcc-5.0/libgcc/libgcc2.c index c7376206d6..0ef8823428 100644 --- a/contrib/gcc-5.0/libgcc/libgcc2.c +++ b/contrib/gcc-5.0/libgcc/libgcc2.c @@ -2209,7 +2209,12 @@ TRANSFER_FROM_TRAMPOLINE #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this - code to run constructors. In that case, we need to handle EH here, too. */ + code to run constructors. In that case, we need to handle EH here, too. + But MINGW32 is special because it handles CRTSTUFF and EH on its own. */ + +#ifdef __MINGW32__ +#undef __LIBGCC_EH_FRAME_SECTION_NAME__ +#endif #ifdef __LIBGCC_EH_FRAME_SECTION_NAME__ #include "unwind-dw2-fde.h" diff --git a/contrib/gcc-5.0/libgomp/oacc-mem.c b/contrib/gcc-5.0/libgomp/oacc-mem.c index 89ef5fcd88..c3e12fab3b 100644 --- a/contrib/gcc-5.0/libgomp/oacc-mem.c +++ b/contrib/gcc-5.0/libgomp/oacc-mem.c @@ -447,7 +447,8 @@ delete_copyout (unsigned f, void *h, size_t s) if (!n) gomp_fatal ("[%p,%d] is not mapped", (void *)h, (int)s); - d = (void *) (n->tgt->tgt_start + n->tgt_offset); + d = (void *) (n->tgt->tgt_start + n->tgt_offset + + (uintptr_t) h - n->host_start); host_size = n->host_end - n->host_start; @@ -490,7 +491,8 @@ update_dev_host (int is_dev, void *h, size_t s) if (!n) gomp_fatal ("[%p,%d] is not mapped", h, (int)s); - d = (void *) (n->tgt->tgt_start + n->tgt_offset); + d = (void *) (n->tgt->tgt_start + n->tgt_offset + + (uintptr_t) h - n->host_start); if (is_dev) acc_dev->host2dev_func (acc_dev->target_id, d, h, s); diff --git a/contrib/gcc-5.0/libiberty/cp-demangle.c b/contrib/gcc-5.0/libiberty/cp-demangle.c index 77c2cee9d1..aef2e9b329 100644 --- a/contrib/gcc-5.0/libiberty/cp-demangle.c +++ b/contrib/gcc-5.0/libiberty/cp-demangle.c @@ -124,6 +124,13 @@ extern char *alloca (); # endif /* alloca */ #endif /* HAVE_ALLOCA_H */ +#ifdef HAVE_LIMITS_H +#include +#endif +#ifndef INT_MAX +# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ +#endif + #include "ansidecl.h" #include "libiberty.h" #include "demangle.h" @@ -394,7 +401,7 @@ d_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds, struct demangle_component *); static struct demangle_component * -d_make_template_param (struct d_info *, long); +d_make_template_param (struct d_info *, int); static struct demangle_component * d_make_sub (struct d_info *, const char *, int); @@ -417,7 +424,7 @@ static struct demangle_component *d_unqualified_name (struct d_info *); static struct demangle_component *d_source_name (struct d_info *); -static long d_number (struct d_info *); +static int d_number (struct d_info *); static struct demangle_component *d_identifier (struct d_info *, int); @@ -538,8 +545,10 @@ d_print_array_type (struct d_print_info *, int, static void d_print_expr_op (struct d_print_info *, int, const struct demangle_component *); -static void -d_print_cast (struct d_print_info *, int, const struct demangle_component *); +static void d_print_cast (struct d_print_info *, int, + const struct demangle_component *); +static void d_print_conversion (struct d_print_info *, int, + const struct demangle_component *); static int d_demangle_callback (const char *, int, demangle_callbackref, void *); @@ -715,7 +724,7 @@ d_dump (struct demangle_component *dc, int indent) case DEMANGLE_COMPONENT_FIXED_TYPE: printf ("fixed-point type, accum? %d, sat? %d\n", dc->u.s_fixed.accum, dc->u.s_fixed.sat); - d_dump (dc->u.s_fixed.length, indent + 2) + d_dump (dc->u.s_fixed.length, indent + 2); break; case DEMANGLE_COMPONENT_ARGLIST: printf ("argument list\n"); @@ -729,6 +738,9 @@ d_dump (struct demangle_component *dc, int indent) case DEMANGLE_COMPONENT_CAST: printf ("cast\n"); break; + case DEMANGLE_COMPONENT_CONVERSION: + printf ("conversion operator\n"); + break; case DEMANGLE_COMPONENT_NULLARY: printf ("nullary operator\n"); break; @@ -938,6 +950,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_IMAGINARY: case DEMANGLE_COMPONENT_VENDOR_TYPE: case DEMANGLE_COMPONENT_CAST: + case DEMANGLE_COMPONENT_CONVERSION: case DEMANGLE_COMPONENT_JAVA_RESOURCE: case DEMANGLE_COMPONENT_DECLTYPE: case DEMANGLE_COMPONENT_PACK_EXPANSION: @@ -1105,7 +1118,7 @@ d_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind, /* Add a new template parameter. */ static struct demangle_component * -d_make_template_param (struct d_info *di, long i) +d_make_template_param (struct d_info *di, int i) { struct demangle_component *p; @@ -1121,7 +1134,7 @@ d_make_template_param (struct d_info *di, long i) /* Add a new function parameter. */ static struct demangle_component * -d_make_function_param (struct d_info *di, long i) +d_make_function_param (struct d_info *di, int i) { struct demangle_component *p; @@ -1229,7 +1242,7 @@ is_ctor_dtor_or_conversion (struct demangle_component *dc) return is_ctor_dtor_or_conversion (d_right (dc)); case DEMANGLE_COMPONENT_CTOR: case DEMANGLE_COMPONENT_DTOR: - case DEMANGLE_COMPONENT_CAST: + case DEMANGLE_COMPONENT_CONVERSION: return 1; } } @@ -1595,7 +1608,7 @@ d_unqualified_name (struct d_info *di) static struct demangle_component * d_source_name (struct d_info *di) { - long len; + int len; struct demangle_component *ret; len = d_number (di); @@ -1608,12 +1621,12 @@ d_source_name (struct d_info *di) /* number ::= [n] <(non-negative decimal integer)> */ -static long +static int d_number (struct d_info *di) { int negative; char peek; - long ret; + int ret; negative = 0; peek = d_peek_char (di); @@ -1785,11 +1798,16 @@ d_operator_name (struct d_info *di) { struct demangle_component *type; int was_conversion = di->is_conversion; + struct demangle_component *res; di->is_conversion = ! di->is_expression; type = cplus_demangle_type (di); + if (di->is_conversion) + res = d_make_comp (di, DEMANGLE_COMPONENT_CONVERSION, type, NULL); + else + res = d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL); di->is_conversion = was_conversion; - return d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL); + return res; } else { @@ -1840,7 +1858,7 @@ d_java_resource (struct d_info *di) { struct demangle_component *p = NULL; struct demangle_component *next = NULL; - long len, i; + int len, i; char c; const char *str; @@ -1982,7 +2000,7 @@ d_special_name (struct d_info *di) case 'C': { struct demangle_component *derived_type; - long offset; + int offset; struct demangle_component *base_type; derived_type = cplus_demangle_type (di); @@ -2905,10 +2923,10 @@ d_pointer_to_member_type (struct d_info *di) /* _ */ -static long +static int d_compact_number (struct d_info *di) { - long num; + int num; if (d_peek_char (di) == '_') num = 0; else if (d_peek_char (di) == 'n') @@ -2916,7 +2934,7 @@ d_compact_number (struct d_info *di) else num = d_number (di) + 1; - if (! d_check_char (di, '_')) + if (num < 0 || ! d_check_char (di, '_')) return -1; return num; } @@ -2928,7 +2946,7 @@ d_compact_number (struct d_info *di) static struct demangle_component * d_template_param (struct d_info *di) { - long param; + int param; if (! d_check_char (di, 'T')) return NULL; @@ -3130,9 +3148,10 @@ d_expression_1 (struct d_info *di) } else { - index = d_compact_number (di) + 1; - if (index == 0) + index = d_compact_number (di); + if (index == INT_MAX || index == -1) return NULL; + index++; } return d_make_function_param (di, index); } @@ -3163,6 +3182,8 @@ d_expression_1 (struct d_info *di) struct demangle_component *type = NULL; if (peek == 't') type = cplus_demangle_type (di); + if (!d_peek_next_char (di)) + return NULL; d_advance (di, 2); return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST, type, d_exprlist (di, 'E')); @@ -3237,6 +3258,8 @@ d_expression_1 (struct d_info *di) struct demangle_component *left; struct demangle_component *right; + if (code == NULL) + return NULL; if (op_is_new_cast (op)) left = cplus_demangle_type (di); else @@ -3264,7 +3287,9 @@ d_expression_1 (struct d_info *di) struct demangle_component *second; struct demangle_component *third; - if (!strcmp (code, "qu")) + if (code == NULL) + return NULL; + else if (!strcmp (code, "qu")) { /* ?: expression. */ first = d_expression_1 (di); @@ -3455,7 +3480,7 @@ d_local_name (struct d_info *di) static int d_discriminator (struct d_info *di) { - long discrim; + int discrim; if (d_peek_char (di) != '_') return 1; @@ -3511,7 +3536,7 @@ static struct demangle_component * d_unnamed_type (struct d_info *di) { struct demangle_component *ret; - long num; + int num; if (! d_check_char (di, 'U')) return NULL; @@ -3891,6 +3916,7 @@ d_count_templates_scopes (int *num_templates, int *num_scopes, case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: case DEMANGLE_COMPONENT_INITIALIZER_LIST: case DEMANGLE_COMPONENT_CAST: + case DEMANGLE_COMPONENT_CONVERSION: case DEMANGLE_COMPONENT_NULLARY: case DEMANGLE_COMPONENT_UNARY: case DEMANGLE_COMPONENT_BINARY: @@ -4037,10 +4063,10 @@ d_append_string (struct d_print_info *dpi, const char *s) } static inline void -d_append_num (struct d_print_info *dpi, long l) +d_append_num (struct d_print_info *dpi, int l) { char buf[25]; - sprintf (buf,"%ld", l); + sprintf (buf,"%d", l); d_append_string (dpi, buf); } @@ -4193,6 +4219,9 @@ d_find_pack (struct d_print_info *dpi, case DEMANGLE_COMPONENT_CHARACTER: case DEMANGLE_COMPONENT_FUNCTION_PARAM: case DEMANGLE_COMPONENT_UNNAMED_TYPE: + case DEMANGLE_COMPONENT_FIXED_TYPE: + case DEMANGLE_COMPONENT_DEFAULT_ARG: + case DEMANGLE_COMPONENT_NUMBER: return NULL; case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: @@ -4428,6 +4457,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options, local_name = d_right (typed_name); if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG) local_name = local_name->u.s_unary_num.sub; + if (local_name == NULL) + { + d_print_error (dpi); + return; + } while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS || local_name->type == DEMANGLE_COMPONENT_CONST_THIS @@ -5016,9 +5050,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options, d_print_comp (dpi, options, dc->u.s_extended_operator.name); return; - case DEMANGLE_COMPONENT_CAST: + case DEMANGLE_COMPONENT_CONVERSION: d_append_string (dpi, "operator "); - d_print_cast (dpi, options, dc); + d_print_conversion (dpi, options, dc); return; case DEMANGLE_COMPONENT_NULLARY: @@ -5751,11 +5785,20 @@ d_print_expr_op (struct d_print_info *dpi, int options, static void d_print_cast (struct d_print_info *dpi, int options, - const struct demangle_component *dc) + const struct demangle_component *dc) +{ + d_print_comp (dpi, options, d_left (dc)); +} + +/* Print a conversion operator. */ + +static void +d_print_conversion (struct d_print_info *dpi, int options, + const struct demangle_component *dc) { struct d_print_template dpt; - /* For a cast operator, we need the template parameters from + /* For a conversion operator, we need the template parameters from the enclosing template in scope for processing the type. */ if (dpi->current_template != NULL) { diff --git a/contrib/gcc-5.0/libiberty/cp-demint.c b/contrib/gcc-5.0/libiberty/cp-demint.c index 1d1a77af74..efcc5b7f5c 100644 --- a/contrib/gcc-5.0/libiberty/cp-demint.c +++ b/contrib/gcc-5.0/libiberty/cp-demint.c @@ -110,6 +110,7 @@ cplus_demangle_fill_component (struct demangle_component *p, case DEMANGLE_COMPONENT_IMAGINARY: case DEMANGLE_COMPONENT_VENDOR_TYPE: case DEMANGLE_COMPONENT_CAST: + case DEMANGLE_COMPONENT_CONVERSION: if (right != NULL) return 0; break; diff --git a/contrib/gcc-5.0/libiberty/cplus-dem.c b/contrib/gcc-5.0/libiberty/cplus-dem.c index c68b9813de..7514e57913 100644 --- a/contrib/gcc-5.0/libiberty/cplus-dem.c +++ b/contrib/gcc-5.0/libiberty/cplus-dem.c @@ -56,6 +56,13 @@ void * malloc (); void * realloc (); #endif +#ifdef HAVE_LIMITS_H +#include +#endif +#ifndef INT_MAX +# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ +#endif + #include #undef CURRENT_DEMANGLING_STYLE #define CURRENT_DEMANGLING_STYLE work->options @@ -1237,11 +1244,13 @@ squangle_mop_up (struct work_stuff *work) { free ((char *) work -> btypevec); work->btypevec = NULL; + work->bsize = 0; } if (work -> ktypevec != NULL) { free ((char *) work -> ktypevec); work->ktypevec = NULL; + work->ksize = 0; } } @@ -2999,6 +3008,11 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp) success = 1; break; } + else if (n == -1) + { + success = 0; + break; + } } else { @@ -4254,6 +4268,8 @@ remember_type (struct work_stuff *work, const char *start, int len) } else { + if (work -> typevec_size > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> typevec_size *= 2; work -> typevec = XRESIZEVEC (char *, work->typevec, work->typevec_size); @@ -4281,6 +4297,8 @@ remember_Ktype (struct work_stuff *work, const char *start, int len) } else { + if (work -> ksize > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> ksize *= 2; work -> ktypevec = XRESIZEVEC (char *, work->ktypevec, work->ksize); @@ -4310,6 +4328,8 @@ register_Btype (struct work_stuff *work) } else { + if (work -> bsize > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> bsize *= 2; work -> btypevec = XRESIZEVEC (char *, work->btypevec, work->bsize); @@ -4764,6 +4784,8 @@ string_need (string *s, int n) else if (s->e - s->p < n) { tem = s->p - s->b; + if (n > INT_MAX / 2 - tem) + xmalloc_failed (INT_MAX); n += tem; n *= 2; s->b = XRESIZEVEC (char, s->b, n); diff --git a/contrib/gcc-5.0/libitm/ChangeLog b/contrib/gcc-5.0/libitm/ChangeLog index cf335388e4..213d243e11 100644 --- a/contrib/gcc-5.0/libitm/ChangeLog +++ b/contrib/gcc-5.0/libitm/ChangeLog @@ -1,3 +1,11 @@ +2016-06-03 Release Manager + + * GCC 5.4.0 released. + +2015-12-04 Release Manager + + * GCC 5.3.0 released. + 2015-07-16 Release Manager * GCC 5.2.0 released. diff --git a/contrib/gcc-5.0/libstdc++-v3/config/cpu/aarch64/atomic_word.h b/contrib/gcc-5.0/libstdc++-v3/config/cpu/aarch64/atomic_word.h deleted file mode 100644 index 4dbfb30826..0000000000 --- a/contrib/gcc-5.0/libstdc++-v3/config/cpu/aarch64/atomic_word.h +++ /dev/null @@ -1,44 +0,0 @@ -// Low-level type for atomic operations -*- C++ -*- - -// 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 -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/** @file atomic_word.h - * This file is a GNU extension to the Standard C++ Library. - */ - -#ifndef _GLIBCXX_ATOMIC_WORD_H -#define _GLIBCXX_ATOMIC_WORD_H 1 - - -typedef int _Atomic_word; - -// This one prevents loads from being hoisted across the barrier; -// in other words, this is a Load-Load acquire barrier. -// This is necessary iff TARGET_RELAXED_ORDERING is defined in tm.h. -#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE) - -// This one prevents stores from being sunk across the barrier; in other -// words, a Store-Store release barrier. -#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE) - -#endif diff --git a/contrib/gcc-5.0/libstdc++-v3/include/backward/strstream b/contrib/gcc-5.0/libstdc++-v3/include/backward/strstream index 9288e56395..10e2dfe343 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/backward/strstream +++ b/contrib/gcc-5.0/libstdc++-v3/include/backward/strstream @@ -40,9 +40,8 @@ // MAY BE REMOVED in a future standard revision. One should use the // header instead. -/** @file backward/strstream - * This is an internal header file, included by other library headers. - * Do not attempt to use it directly. @headername{sstream} +/** @file strstream + * This is a Standard C++ Library header. */ #ifndef _BACKWARD_STRSTREAM 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 12c6c12f18..615e071096 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 @@ -409,7 +409,7 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, * Calls @c __a.destroy(__p) if that expression is well-formed, * otherwise calls @c __p->~_Tp() */ - template + template static void destroy(_Alloc& __a, _Tp* __p) { _S_destroy(__a, __p); } @@ -437,6 +437,130 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, { return _S_select(__rhs, 0); } }; + /// Partial specialization for std::allocator. + template + struct allocator_traits> + { + /// The allocator type + using allocator_type = allocator<_Tp>; + /// The allocated type + using value_type = _Tp; + + /// The allocator's pointer type. + using pointer = _Tp*; + + /// The allocator's const pointer type. + using const_pointer = const _Tp*; + + /// The allocator's void pointer type. + using void_pointer = void*; + + /// The allocator's const void pointer type. + using const_void_pointer = const void*; + + /// The allocator's difference type + using difference_type = std::ptrdiff_t; + + /// The allocator's size type + using size_type = std::size_t; + + /// How the allocator is propagated on copy assignment + using propagate_on_container_copy_assignment = false_type; + + /// How the allocator is propagated on move assignment + using propagate_on_container_move_assignment = true_type; + + /// How the allocator is propagated on swap + using propagate_on_container_swap = false_type; + + template + using rebind_alloc = allocator<_Up>; + + template + using rebind_traits = allocator_traits>; + + /** + * @brief Allocate memory. + * @param __a An allocator. + * @param __n The number of objects to allocate space for. + * + * Calls @c a.allocate(n) + */ + static pointer + allocate(allocator_type& __a, size_type __n) + { return __a.allocate(__n); } + + /** + * @brief Allocate memory. + * @param __a An allocator. + * @param __n The number of objects to allocate space for. + * @param __hint Aid to locality. + * @return Memory of suitable size and alignment for @a n objects + * of type @c value_type + * + * Returns a.allocate(n, hint) + */ + static pointer + allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) + { return __a.allocate(__n, __hint); } + + /** + * @brief Deallocate memory. + * @param __a An allocator. + * @param __p Pointer to the memory to deallocate. + * @param __n The number of objects space was allocated for. + * + * Calls a.deallocate(p, n) + */ + static void + deallocate(allocator_type& __a, pointer __p, size_type __n) + { __a.deallocate(__p, __n); } + + /** + * @brief Construct an object of type @a _Up + * @param __a An allocator. + * @param __p Pointer to memory of suitable size and alignment for Tp + * @param __args Constructor arguments. + * + * Calls __a.construct(__p, std::forward(__args)...) + */ + template + static void + construct(allocator_type& __a, _Up* __p, _Args&&... __args) + { __a.construct(__p, std::forward<_Args>(__args)...); } + + /** + * @brief Destroy an object of type @a _Up + * @param __a An allocator. + * @param __p Pointer to the object to destroy + * + * Calls @c __a.destroy(__p). + */ + template + static void + destroy(allocator_type& __a, _Up* __p) + { __a.destroy(__p); } + + /** + * @brief The maximum supported allocation size + * @param __a An allocator. + * @return @c __a.max_size() + */ + static size_type + max_size(const allocator_type& __a) noexcept + { return __a.max_size(); } + + /** + * @brief Obtain an allocator to use when copying a container. + * @param __rhs An allocator. + * @return @c __rhs + */ + static allocator_type + select_on_container_copy_construction(const allocator_type& __rhs) + { return __rhs; } + }; + + template inline void __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type) 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 19222d1383..4020dcb2e2 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 @@ -322,7 +322,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) - _GLIBCXX_NOEXCEPT { for (; __k1 != __k2; ++__k1, ++__p) traits_type::assign(*__p, *__k1); // These types are off. @@ -388,7 +387,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @brief Construct an empty string using allocator @a a. */ explicit - basic_string(const _Alloc& __a) + basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT : _M_dataplus(_M_local_data(), __a) { _M_set_length(0); } @@ -397,7 +396,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @param __str Source string. */ basic_string(const basic_string& __str) - : _M_dataplus(_M_local_data(), __str._M_get_allocator()) // TODO A traits + : _M_dataplus(_M_local_data(), + _Alloc_traits::_S_select_on_copy(__str._M_get_allocator())) { _M_construct(__str._M_data(), __str._M_data() + __str.length()); } /** @@ -510,10 +510,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { _M_construct(__str.begin(), __str.end()); } basic_string(basic_string&& __str, const _Alloc& __a) + noexcept(_Alloc_traits::_S_always_equal()) : _M_dataplus(_M_local_data(), __a) { - if (__str.get_allocator() == __a) - *this = std::move(__str); + if (__str._M_is_local()) + { + traits_type::copy(_M_local_buf, __str._M_local_buf, + _S_local_capacity + 1); + _M_length(__str.length()); + __str._M_set_length(0); + } + else if (_Alloc_traits::_S_always_equal() + || __str.get_allocator() == __a) + { + _M_data(__str._M_data()); + _M_length(__str.length()); + _M_capacity(__str._M_allocated_capacity); + __str._M_data(__str._M_local_buf); + __str._M_set_length(0); + } else _M_construct(__str.begin(), __str.end()); } @@ -549,7 +564,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ basic_string& operator=(const basic_string& __str) - { return this->assign(__str); } + { +#if __cplusplus >= 201103L + if (_Alloc_traits::_S_propagate_on_copy_assign()) + { + if (!_Alloc_traits::_S_always_equal() && !_M_is_local() + && _M_get_allocator() != __str._M_get_allocator()) + { + // replacement allocator cannot free existing storage + _M_destroy(_M_allocated_capacity); + _M_data(_M_local_data()); + _M_set_length(0); + } + std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator()); + } +#endif + return this->assign(__str); + } /** * @brief Copy contents of @a s into this string. @@ -586,8 +617,51 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 // 2063. Contradictory requirements for string move assignment basic_string& operator=(basic_string&& __str) + noexcept(_Alloc_traits::_S_nothrow_move()) { - this->swap(__str); + if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign() + && !_Alloc_traits::_S_always_equal() + && _M_get_allocator() != __str._M_get_allocator()) + { + // Destroy existing storage before replacing allocator. + _M_destroy(_M_allocated_capacity); + _M_data(_M_local_data()); + _M_set_length(0); + } + // Replace allocator if POCMA is true. + std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator()); + + if (!__str._M_is_local() + && (_Alloc_traits::_S_propagate_on_move_assign() + || _Alloc_traits::_S_always_equal())) + { + pointer __data = nullptr; + size_type __capacity; + if (!_M_is_local()) + { + if (_Alloc_traits::_S_always_equal()) + { + __data = _M_data(); + __capacity = _M_allocated_capacity; + } + else + _M_destroy(_M_allocated_capacity); + } + + _M_data(__str._M_data()); + _M_length(__str.length()); + _M_capacity(__str._M_allocated_capacity); + if (__data) + { + __str._M_data(__data); + __str._M_capacity(__capacity); + } + else + __str._M_data(__str._M_local_buf); + } + else + assign(__str); + __str.clear(); return *this; } @@ -1108,6 +1182,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ basic_string& assign(basic_string&& __str) + noexcept(_Alloc_traits::_S_nothrow_move()) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2063. Contradictory requirements for string move assignment @@ -2782,7 +2857,6 @@ _GLIBCXX_END_NAMESPACE_CXX11 template static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) - _GLIBCXX_NOEXCEPT { for (; __k1 != __k2; ++__k1, ++__p) traits_type::assign(*__p, *__k1); // These types are off. @@ -4905,13 +4979,14 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline bool operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) == 0; } template inline typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type operator==(const basic_string<_CharT>& __lhs, - const basic_string<_CharT>& __rhs) + const basic_string<_CharT>& __rhs) _GLIBCXX_NOEXCEPT { return (__lhs.size() == __rhs.size() && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(), __lhs.size())); } @@ -4951,6 +5026,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline bool operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + _GLIBCXX_NOEXCEPT { return !(__lhs == __rhs); } /** @@ -4988,6 +5064,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline bool operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) < 0; } /** @@ -5025,6 +5102,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline bool operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) > 0; } /** @@ -5062,6 +5140,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline bool operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) <= 0; } /** @@ -5099,6 +5178,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline bool operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) >= 0; } /** @@ -5136,6 +5216,9 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline void swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, basic_string<_CharT, _Traits, _Alloc>& __rhs) +#if __cplusplus >= 201103L + noexcept(noexcept(__lhs.swap(__rhs))) +#endif { __lhs.swap(__rhs); } diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.tcc b/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.tcc index b9da93bf17..56af86471e 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.tcc +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.tcc @@ -61,11 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (this == &__s) return; - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 431. Swapping containers with unequal allocators. - // TODO propagation traits - std::__alloc_swap::_S_do_it(_M_get_allocator(), - __s._M_get_allocator()); + _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator()); if (_M_is_local()) if (__s._M_is_local()) @@ -404,7 +400,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__new_size <= this->capacity()) { - _CharT* __p = this->_M_data() + __pos1; + pointer __p = this->_M_data() + __pos1; const size_type __how_much = __old_size - __pos1 - __n1; if (__how_much && __n1 != __n2) @@ -433,7 +429,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__new_size <= this->capacity()) { - _CharT* __p = this->_M_data() + __pos; + pointer __p = this->_M_data() + __pos; const size_type __how_much = __old_size - __pos - __len1; if (_M_disjunct(__s)) diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/c++0x_warning.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/c++0x_warning.h index 5c7e972022..dabc2c4fd2 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/c++0x_warning.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/c++0x_warning.h @@ -29,9 +29,9 @@ #define _CXX0X_WARNING_H 1 #if __cplusplus < 201103L -#error This file requires compiler and library support for the \ -ISO C++ 2011 standard. This support is currently experimental, and must be \ -enabled with the -std=c++11 or -std=gnu++11 compiler options. +#error This file requires compiler and library support \ +for the ISO C++ 2011 standard. This support must be enabled \ +with the -std=c++11 or -std=gnu++11 compiler options. #endif #endif diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/c++config b/contrib/gcc-5.0/libstdc++-v3/include/bits/c++config index ae3065feaa..79d1b368d4 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/c++config +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/c++config @@ -294,7 +294,7 @@ namespace std # endif # if _GLIBCXX_USE_CXX11_ABI - inline namespace __cxx11 __attribute__((__abi_tag__)) { } + inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } # endif } diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/forward_list.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/forward_list.h index 88eee1f745..0cdd75bd41 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/forward_list.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/forward_list.h @@ -463,7 +463,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * @brief Creates a %forward_list with default constructed elements. - * @param __n The number of elements to initially create. + * @param __n The number of elements to initially create. + * @param __al An allocator object. * * This constructor creates the %forward_list with @a __n default * constructed elements. @@ -1083,6 +1084,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * after @a __pos in constant time. * * Undefined if @a __pos is in (__before,__last). + * @{ */ void splice_after(const_iterator __pos, forward_list&&, @@ -1093,6 +1095,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER splice_after(const_iterator __pos, forward_list&, const_iterator __before, const_iterator __last) { _M_splice_after(__pos, __before, __last); } + // @} /** * @brief Remove all elements equal to value. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_facets_nonio.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_facets_nonio.h index 7eae6c8065..527296b78f 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_facets_nonio.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_facets_nonio.h @@ -709,7 +709,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * * @param __s Start of string to parse. * @param __end End of string to parse. - * @param __io Source of the locale. + * @param __f Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @param __format Format specifier. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/random.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/random.h index 8caade5082..d152722aef 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/random.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/random.h @@ -32,6 +32,7 @@ #define _RANDOM_H 1 #include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -149,14 +150,6 @@ _GLIBCXX_END_NAMESPACE_VERSION __mod(_Tp __x) { return _Mod<_Tp, __m, __a, __c>::__calc(__x); } - /* Determine whether number is a power of 2. */ - template - inline bool - _Power_of_2(_Tp __x) - { - return ((__x - 1) & __x) == 0; - }; - /* * An adaptor class for converting the output of any Generator into * the input for a specific Distribution. @@ -1656,164 +1649,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - /** - * @brief Uniform discrete distribution for random numbers. - * A discrete random distribution on the range @f$[min, max]@f$ with equal - * probability throughout the range. - */ - template - class uniform_int_distribution - { - static_assert(std::is_integral<_IntType>::value, - "template argument not an integral type"); - - public: - /** The type of the range of the distribution. */ - typedef _IntType result_type; - /** Parameter type. */ - struct param_type - { - typedef uniform_int_distribution<_IntType> distribution_type; - - explicit - param_type(_IntType __a = 0, - _IntType __b = std::numeric_limits<_IntType>::max()) - : _M_a(__a), _M_b(__b) - { - _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b); - } - - result_type - a() const - { return _M_a; } - - result_type - b() const - { return _M_b; } - - friend bool - operator==(const param_type& __p1, const param_type& __p2) - { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } - - private: - _IntType _M_a; - _IntType _M_b; - }; - - public: - /** - * @brief Constructs a uniform distribution object. - */ - explicit - uniform_int_distribution(_IntType __a = 0, - _IntType __b = std::numeric_limits<_IntType>::max()) - : _M_param(__a, __b) - { } - - explicit - uniform_int_distribution(const param_type& __p) - : _M_param(__p) - { } - - /** - * @brief Resets the distribution state. - * - * Does nothing for the uniform integer distribution. - */ - void - reset() { } - - result_type - a() const - { return _M_param.a(); } - - result_type - b() const - { return _M_param.b(); } - - /** - * @brief Returns the parameter set of the distribution. - */ - param_type - param() const - { return _M_param; } - - /** - * @brief Sets the parameter set of the distribution. - * @param __param The new parameter set of the distribution. - */ - void - param(const param_type& __param) - { _M_param = __param; } - - /** - * @brief Returns the inclusive lower bound of the distribution range. - */ - result_type - min() const - { return this->a(); } - - /** - * @brief Returns the inclusive upper bound of the distribution range. - */ - result_type - max() const - { return this->b(); } - - /** - * @brief Generating functions. - */ - template - result_type - operator()(_UniformRandomNumberGenerator& __urng) - { return this->operator()(__urng, _M_param); } - - template - result_type - operator()(_UniformRandomNumberGenerator& __urng, - const param_type& __p); - - template - void - __generate(_ForwardIterator __f, _ForwardIterator __t, - _UniformRandomNumberGenerator& __urng) - { this->__generate(__f, __t, __urng, _M_param); } - - template - void - __generate(_ForwardIterator __f, _ForwardIterator __t, - _UniformRandomNumberGenerator& __urng, - const param_type& __p) - { this->__generate_impl(__f, __t, __urng, __p); } - - template - void - __generate(result_type* __f, result_type* __t, - _UniformRandomNumberGenerator& __urng, - const param_type& __p) - { this->__generate_impl(__f, __t, __urng, __p); } - - /** - * @brief Return true if two uniform integer distributions have - * the same parameters. - */ - friend bool - operator==(const uniform_int_distribution& __d1, - const uniform_int_distribution& __d2) - { return __d1._M_param == __d2._M_param; } - - private: - template - void - __generate_impl(_ForwardIterator __f, _ForwardIterator __t, - _UniformRandomNumberGenerator& __urng, - const param_type& __p); - - param_type _M_param; - }; + // std::uniform_int_distribution is defined in /** * @brief Return true if two uniform integer distributions have diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/random.tcc b/contrib/gcc-5.0/libstdc++-v3/include/bits/random.tcc index f10d052f90..d092cacf0c 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/random.tcc +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/random.tcc @@ -872,158 +872,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } - template - template - typename uniform_int_distribution<_IntType>::result_type - uniform_int_distribution<_IntType>:: - operator()(_UniformRandomNumberGenerator& __urng, - const param_type& __param) - { - typedef typename _UniformRandomNumberGenerator::result_type - _Gresult_type; - typedef typename std::make_unsigned::type __utype; - typedef typename std::common_type<_Gresult_type, __utype>::type - __uctype; - - const __uctype __urngmin = __urng.min(); - const __uctype __urngmax = __urng.max(); - const __uctype __urngrange = __urngmax - __urngmin; - const __uctype __urange - = __uctype(__param.b()) - __uctype(__param.a()); - - __uctype __ret; - - if (__urngrange > __urange) - { - // downscaling - const __uctype __uerange = __urange + 1; // __urange can be zero - const __uctype __scaling = __urngrange / __uerange; - const __uctype __past = __uerange * __scaling; - do - __ret = __uctype(__urng()) - __urngmin; - while (__ret >= __past); - __ret /= __scaling; - } - else if (__urngrange < __urange) - { - // upscaling - /* - Note that every value in [0, urange] - can be written uniquely as - - (urngrange + 1) * high + low - - where - - high in [0, urange / (urngrange + 1)] - - and - - low in [0, urngrange]. - */ - __uctype __tmp; // wraparound control - do - { - const __uctype __uerngrange = __urngrange + 1; - __tmp = (__uerngrange * operator() - (__urng, param_type(0, __urange / __uerngrange))); - __ret = __tmp + (__uctype(__urng()) - __urngmin); - } - while (__ret > __urange || __ret < __tmp); - } - else - __ret = __uctype(__urng()) - __urngmin; - - return __ret + __param.a(); - } - - - template - template - void - uniform_int_distribution<_IntType>:: - __generate_impl(_ForwardIterator __f, _ForwardIterator __t, - _UniformRandomNumberGenerator& __urng, - const param_type& __param) - { - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) - typedef typename _UniformRandomNumberGenerator::result_type - _Gresult_type; - typedef typename std::make_unsigned::type __utype; - typedef typename std::common_type<_Gresult_type, __utype>::type - __uctype; - - const __uctype __urngmin = __urng.min(); - const __uctype __urngmax = __urng.max(); - const __uctype __urngrange = __urngmax - __urngmin; - const __uctype __urange - = __uctype(__param.b()) - __uctype(__param.a()); - - __uctype __ret; - - if (__urngrange > __urange) - { - if (__detail::_Power_of_2(__urngrange + 1) - && __detail::_Power_of_2(__urange + 1)) - { - while (__f != __t) - { - __ret = __uctype(__urng()) - __urngmin; - *__f++ = (__ret & __urange) + __param.a(); - } - } - else - { - // downscaling - const __uctype __uerange = __urange + 1; // __urange can be zero - const __uctype __scaling = __urngrange / __uerange; - const __uctype __past = __uerange * __scaling; - while (__f != __t) - { - do - __ret = __uctype(__urng()) - __urngmin; - while (__ret >= __past); - *__f++ = __ret / __scaling + __param.a(); - } - } - } - else if (__urngrange < __urange) - { - // upscaling - /* - Note that every value in [0, urange] - can be written uniquely as - - (urngrange + 1) * high + low - - where - - high in [0, urange / (urngrange + 1)] - - and - - low in [0, urngrange]. - */ - __uctype __tmp; // wraparound control - while (__f != __t) - { - do - { - const __uctype __uerngrange = __urngrange + 1; - __tmp = (__uerngrange * operator() - (__urng, param_type(0, __urange / __uerngrange))); - __ret = __tmp + (__uctype(__urng()) - __urngmin); - } - while (__ret > __urange || __ret < __tmp); - *__f++ = __ret; - } - } - else - while (__f != __t) - *__f++ = __uctype(__urng()) - __urngmin + __param.a(); - } - template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_executor.tcc b/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_executor.tcc index f06549964d..de217da58d 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_executor.tcc +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_executor.tcc @@ -147,7 +147,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_lookahead(_State<_TraitsT> __state) { - _ResultsVec __what(_M_cur_results.size()); + // Backreferences may refer to captured content. + // We may want to make this faster by not copying, + // but let's not be clever prematurely. + _ResultsVec __what(_M_cur_results); _Executor __sub(_M_current, _M_end, __what, _M_re, _M_flags); __sub._M_states._M_start = __state._M_alt; if (__sub._M_search_from_first()) diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.h index b47103e827..6fefed76c8 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.h @@ -95,11 +95,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_awk_escape_tbl), _M_spec_char(_M_is_ecma() ? _M_ecma_spec_char - : _M_is_basic() + : _M_flags & regex_constants::basic ? _M_basic_spec_char - : _M_extended_spec_char), + : _M_flags & regex_constants::extended + ? _M_extended_spec_char + : _M_flags & regex_constants::grep + ? ".[\\*^$\n" + : _M_flags & regex_constants::egrep + ? ".[\\()*+?{|^$\n" + : _M_flags & regex_constants::awk + ? _M_extended_spec_char + : nullptr), _M_at_bracket_start(false) - { } + { __glibcxx_assert(_M_spec_char); } protected: const char* @@ -137,6 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_flags & regex_constants::awk; } protected: + // TODO: Make them static in the next abi change. const std::pair _M_token_tbl[9] = { {'^', _S_token_line_begin}, diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.tcc b/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.tcc index 1555669393..4658f99e8d 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.tcc +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/regex_scanner.tcc @@ -97,9 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_scan_normal() { auto __c = *_M_current++; - const char* __pos; - if (std::strchr(_M_spec_char, _M_ctype.narrow(__c, '\0')) == nullptr) + if (std::strchr(_M_spec_char, _M_ctype.narrow(__c, ' ')) == nullptr) { _M_token = _S_token_ord_char; _M_value.assign(1, __c); @@ -171,12 +170,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_state = _S_state_in_brace; _M_token = _S_token_interval_begin; } - else if (((__pos = std::strchr(_M_spec_char, _M_ctype.narrow(__c, '\0'))) - != nullptr - && *__pos != '\0' - && __c != ']' - && __c != '}') - || (_M_is_grep() && __c == '\n')) + else if (__c != ']' && __c != '}') { auto __it = _M_token_tbl; auto __narrowc = _M_ctype.narrow(__c, '\0'); diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr.h index f96c07835b..26a0ad3d7b 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr.h @@ -582,19 +582,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept { _M_weak_this._M_assign(__p, __n); } - template + template friend void - __enable_shared_from_this_helper(const __shared_count<>& __pn, - const enable_shared_from_this* __pe, - const _Tp1* __px) noexcept - { - if (__pe != 0) - __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); - } + __enable_shared_from_this_helper(const __shared_count<>&, + const enable_shared_from_this<_Tp1>*, + const _Tp2*) noexcept; mutable weak_ptr<_Tp> _M_weak_this; }; + template + inline void + __enable_shared_from_this_helper(const __shared_count<>& __pn, + const enable_shared_from_this<_Tp1>* + __pe, const _Tp2* __px) noexcept + { + if (__pe != nullptr) + __pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn); + } + /** * @brief Create an object that is owned by a shared_ptr. * @param __a An allocator. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr_base.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr_base.h index 8c3af1285a..d71df31a0a 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1540,19 +1540,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept { _M_weak_this._M_assign(__p, __n); } - template + template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2> friend void - __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, - const __enable_shared_from_this* __pe, - const _Tp1* __px) noexcept - { - if (__pe != 0) - __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); - } + __enable_shared_from_this_helper(const __shared_count<_Lp1>&, + const __enable_shared_from_this<_Tp1, + _Lp1>*, const _Tp2*) noexcept; mutable __weak_ptr<_Tp, _Lp> _M_weak_this; }; + template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2> + inline void + __enable_shared_from_this_helper(const __shared_count<_Lp1>& __pn, + const __enable_shared_from_this<_Tp1, + _Lp1>* __pe, + const _Tp2* __px) noexcept + { + if (__pe != nullptr) + __pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn); + } template inline __shared_ptr<_Tp, _Lp> diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algo.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algo.h index 53c455b16f..77bb37ae92 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algo.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algo.h @@ -63,7 +63,7 @@ #include #if __cplusplus >= 201103L -#include // for std::uniform_int_distribution +#include #endif // See concept_check.h for the __glibcxx_*_requires macros. 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 2b69e61895..68959fa3ef 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 @@ -373,9 +373,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) { #if __cplusplus >= 201103L + using __assignable = conditional<_IsMove, + is_move_assignable<_Tp>, + is_copy_assignable<_Tp>>; // trivial types can have deleted assignment - static_assert( is_copy_assignable<_Tp>::value, - "type is not assignable" ); + static_assert( __assignable::type::value, "type is not assignable" ); #endif const ptrdiff_t _Num = __last - __first; if (_Num) @@ -573,9 +575,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result) { #if __cplusplus >= 201103L + using __assignable = conditional<_IsMove, + is_move_assignable<_Tp>, + is_copy_assignable<_Tp>>; // trivial types can have deleted assignment - static_assert( is_copy_assignable<_Tp>::value, - "type is not assignable" ); + static_assert( __assignable::type::value, "type is not assignable" ); #endif const ptrdiff_t _Num = __last - __first; if (_Num) diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_iterator.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_iterator.h index 7b5872ee0e..55e67a7d8b 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_iterator.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_iterator.h @@ -324,9 +324,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return !(__x < __y); } template +#if __cplusplus < 201103L inline typename reverse_iterator<_Iterator>::difference_type operator-(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) +#else + inline auto + operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + -> decltype(__x.base() - __y.base()) +#endif { return __y.base() - __x.base(); } template 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 d39042f1aa..27bf6b3fdf 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 @@ -841,7 +841,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } _Rb_tree(_Rb_tree&& __x) - : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator()) + : _M_impl(__x._M_impl._M_key_compare, + std::move(__x._M_get_Node_allocator())) { if (__x._M_root() != 0) _M_move_data(__x, std::true_type()); @@ -1245,7 +1246,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L _Rb_tree& - operator=(_Rb_tree&&) noexcept(_Alloc_traits::_S_nothrow_move()); + operator=(_Rb_tree&&) + noexcept(_Alloc_traits::_S_nothrow_move() + && is_nothrow_move_assignable<_Compare>::value); template void @@ -1264,6 +1267,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // which might result in a copy not a move. void _M_move_data(_Rb_tree&, std::false_type); + + // Move assignment from container with equal allocator. + void + _M_move_assign(_Rb_tree&, std::true_type); + + // Move assignment from container with possibly non-equal allocator, + // which might result in a copy not a move. + void + _M_move_assign(_Rb_tree&, std::false_type); #endif }; @@ -1379,23 +1391,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template - _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& + inline void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: - operator=(_Rb_tree&& __x) - noexcept(_Alloc_traits::_S_nothrow_move()) + _M_move_assign(_Rb_tree& __x, true_type) { - _M_impl._M_key_compare = __x._M_impl._M_key_compare; - if (_Alloc_traits::_S_propagate_on_move_assign() - || _Alloc_traits::_S_always_equal() - || _M_get_Node_allocator() == __x._M_get_Node_allocator()) - { - clear(); - if (__x._M_root() != nullptr) - _M_move_data(__x, std::true_type()); - std::__alloc_on_move(_M_get_Node_allocator(), - __x._M_get_Node_allocator()); - return *this; - } + clear(); + if (__x._M_root() != nullptr) + _M_move_data(__x, std::true_type()); + std::__alloc_on_move(_M_get_Node_allocator(), + __x._M_get_Node_allocator()); + } + + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_move_assign(_Rb_tree& __x, false_type) + { + if (_M_get_Node_allocator() == __x._M_get_Node_allocator()) + return _M_move_assign(__x, true_type{}); // Try to move each node reusing existing nodes and copying __x nodes // structure. @@ -1415,6 +1429,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_impl._M_node_count = __x._M_impl._M_node_count; __x.clear(); } + } + + template + inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + operator=(_Rb_tree&& __x) + noexcept(_Alloc_traits::_S_nothrow_move() + && is_nothrow_move_assignable<_Compare>::value) + { + _M_impl._M_key_compare = __x._M_impl._M_key_compare; + constexpr bool __move_storage = + _Alloc_traits::_S_propagate_on_move_assign() + || _Alloc_traits::_S_always_equal(); + _M_move_assign(__x, __bool_constant<__move_storage>()); return *this; } diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/uniform_int_dist.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/uniform_int_dist.h new file mode 100644 index 0000000000..670e379532 --- /dev/null +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/uniform_int_dist.h @@ -0,0 +1,369 @@ +// Class template uniform_int_distribution -*- C++ -*- + +// Copyright (C) 2009-2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** + * @file bits/uniform_int_dist.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{random} + */ + +#ifndef _GLIBCXX_BITS_UNIFORM_INT_DIST_H +#define _GLIBCXX_BITS_UNIFORM_INT_DIST_H + +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + namespace __detail + { + /* Determine whether number is a power of 2. */ + template + inline bool + _Power_of_2(_Tp __x) + { + return ((__x - 1) & __x) == 0; + }; + } + + /** + * @brief Uniform discrete distribution for random numbers. + * + * A discrete random distribution on the range @f$[min, max]@f$ with equal + * probability throughout the range. + * + * @ingroup random_distributions_uniform + */ + template + class uniform_int_distribution + { + static_assert(std::is_integral<_IntType>::value, + "template argument not an integral type"); + + public: + /** The type of the range of the distribution. */ + typedef _IntType result_type; + /** Parameter type. */ + struct param_type + { + typedef uniform_int_distribution<_IntType> distribution_type; + + explicit + param_type(_IntType __a = 0, + _IntType __b = std::numeric_limits<_IntType>::max()) + : _M_a(__a), _M_b(__b) + { + _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b); + } + + result_type + a() const + { return _M_a; } + + result_type + b() const + { return _M_b; } + + friend bool + operator==(const param_type& __p1, const param_type& __p2) + { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } + + private: + _IntType _M_a; + _IntType _M_b; + }; + + public: + /** + * @brief Constructs a uniform distribution object. + */ + explicit + uniform_int_distribution(_IntType __a = 0, + _IntType __b = std::numeric_limits<_IntType>::max()) + : _M_param(__a, __b) + { } + + explicit + uniform_int_distribution(const param_type& __p) + : _M_param(__p) + { } + + /** + * @brief Resets the distribution state. + * + * Does nothing for the uniform integer distribution. + */ + void + reset() { } + + result_type + a() const + { return _M_param.a(); } + + result_type + b() const + { return _M_param.b(); } + + /** + * @brief Returns the parameter set of the distribution. + */ + param_type + param() const + { return _M_param; } + + /** + * @brief Sets the parameter set of the distribution. + * @param __param The new parameter set of the distribution. + */ + void + param(const param_type& __param) + { _M_param = __param; } + + /** + * @brief Returns the inclusive lower bound of the distribution range. + */ + result_type + min() const + { return this->a(); } + + /** + * @brief Returns the inclusive upper bound of the distribution range. + */ + result_type + max() const + { return this->b(); } + + /** + * @brief Generating functions. + */ + template + result_type + operator()(_UniformRandomNumberGenerator& __urng) + { return this->operator()(__urng, _M_param); } + + template + result_type + operator()(_UniformRandomNumberGenerator& __urng, + const param_type& __p); + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, _M_param); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + /** + * @brief Return true if two uniform integer distributions have + * the same parameters. + */ + friend bool + operator==(const uniform_int_distribution& __d1, + const uniform_int_distribution& __d2) + { return __d1._M_param == __d2._M_param; } + + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + + param_type _M_param; + }; + + template + template + typename uniform_int_distribution<_IntType>::result_type + uniform_int_distribution<_IntType>:: + operator()(_UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + typedef typename _UniformRandomNumberGenerator::result_type + _Gresult_type; + typedef typename std::make_unsigned::type __utype; + typedef typename std::common_type<_Gresult_type, __utype>::type + __uctype; + + const __uctype __urngmin = __urng.min(); + const __uctype __urngmax = __urng.max(); + const __uctype __urngrange = __urngmax - __urngmin; + const __uctype __urange + = __uctype(__param.b()) - __uctype(__param.a()); + + __uctype __ret; + + if (__urngrange > __urange) + { + // downscaling + const __uctype __uerange = __urange + 1; // __urange can be zero + const __uctype __scaling = __urngrange / __uerange; + const __uctype __past = __uerange * __scaling; + do + __ret = __uctype(__urng()) - __urngmin; + while (__ret >= __past); + __ret /= __scaling; + } + else if (__urngrange < __urange) + { + // upscaling + /* + Note that every value in [0, urange] + can be written uniquely as + + (urngrange + 1) * high + low + + where + + high in [0, urange / (urngrange + 1)] + + and + + low in [0, urngrange]. + */ + __uctype __tmp; // wraparound control + do + { + const __uctype __uerngrange = __urngrange + 1; + __tmp = (__uerngrange * operator() + (__urng, param_type(0, __urange / __uerngrange))); + __ret = __tmp + (__uctype(__urng()) - __urngmin); + } + while (__ret > __urange || __ret < __tmp); + } + else + __ret = __uctype(__urng()) - __urngmin; + + return __ret + __param.a(); + } + + + template + template + void + uniform_int_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + typedef typename _UniformRandomNumberGenerator::result_type + _Gresult_type; + typedef typename std::make_unsigned::type __utype; + typedef typename std::common_type<_Gresult_type, __utype>::type + __uctype; + + const __uctype __urngmin = __urng.min(); + const __uctype __urngmax = __urng.max(); + const __uctype __urngrange = __urngmax - __urngmin; + const __uctype __urange + = __uctype(__param.b()) - __uctype(__param.a()); + + __uctype __ret; + + if (__urngrange > __urange) + { + if (__detail::_Power_of_2(__urngrange + 1) + && __detail::_Power_of_2(__urange + 1)) + { + while (__f != __t) + { + __ret = __uctype(__urng()) - __urngmin; + *__f++ = (__ret & __urange) + __param.a(); + } + } + else + { + // downscaling + const __uctype __uerange = __urange + 1; // __urange can be zero + const __uctype __scaling = __urngrange / __uerange; + const __uctype __past = __uerange * __scaling; + while (__f != __t) + { + do + __ret = __uctype(__urng()) - __urngmin; + while (__ret >= __past); + *__f++ = __ret / __scaling + __param.a(); + } + } + } + else if (__urngrange < __urange) + { + // upscaling + /* + Note that every value in [0, urange] + can be written uniquely as + + (urngrange + 1) * high + low + + where + + high in [0, urange / (urngrange + 1)] + + and + + low in [0, urngrange]. + */ + __uctype __tmp; // wraparound control + while (__f != __t) + { + do + { + const __uctype __uerngrange = __urngrange + 1; + __tmp = (__uerngrange * operator() + (__urng, param_type(0, __urange / __uerngrange))); + __ret = __tmp + (__uctype(__urng()) - __urngmin); + } + while (__ret > __urange || __ret < __tmp); + *__f++ = __ret; + } + } + else + while (__f != __t) + *__f++ = __uctype(__urng()) - __urngmin + __param.a(); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/valarray_before.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/valarray_before.h index 6cc95747f5..498c5731ad 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/valarray_before.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/valarray_before.h @@ -331,14 +331,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return pow(__x, __y); } }; + template + struct __fun_with_valarray + { + typedef _Tp result_type; + }; + + template + struct __fun_with_valarray<_Tp, false> + { + // No result type defined for invalid value types. + }; // We need these bits in order to recover the return type of // some functions/operators now that we're no longer using // function templates. template - struct __fun + struct __fun : __fun_with_valarray<_Tp> { - typedef _Tp result_type; }; // several specializations for relational operators. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/c_global/cmath b/contrib/gcc-5.0/libstdc++-v3/include/c_global/cmath index 4cafe5f7fe..d3fc8b7f39 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/c_global/cmath +++ b/contrib/gcc-5.0/libstdc++-v3/include/c_global/cmath @@ -880,7 +880,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION signbit(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; - return __builtin_signbit(__type(__f)); + return sizeof(__type) == sizeof(float) + ? __builtin_signbitf(__type(__f)) + : sizeof(__type) == sizeof(double) + ? __builtin_signbit(__type(__f)) + : __builtin_signbitl(__type(__f)); } template diff --git a/contrib/gcc-5.0/libstdc++-v3/include/debug/string b/contrib/gcc-5.0/libstdc++-v3/include/debug/string index 3793a35869..6e07e9fb32 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/debug/string +++ b/contrib/gcc-5.0/libstdc++-v3/include/debug/string @@ -36,18 +36,19 @@ namespace __gnu_debug { - /// Class std::basic_string with safety/checking/debug instrumentation. - template, - typename _Allocator = std::allocator<_CharT> > - class basic_string - : public __gnu_debug::_Safe_container< - basic_string<_CharT, _Traits, _Allocator>, - _Allocator, _Safe_sequence, false>, - public std::basic_string<_CharT, _Traits, _Allocator> - { - typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; - typedef __gnu_debug::_Safe_container< - basic_string, _Allocator, _Safe_sequence, false> _Safe; +/// Class std::basic_string with safety/checking/debug instrumentation. +template, + typename _Allocator = std::allocator<_CharT> > + class basic_string + : public __gnu_debug::_Safe_container< + basic_string<_CharT, _Traits, _Allocator>, + _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>, + public std::basic_string<_CharT, _Traits, _Allocator> + { + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_container< + basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)> + _Safe; public: // types: @@ -71,9 +72,15 @@ namespace __gnu_debug using _Base::npos; + basic_string() +#if __cplusplus >= 201103L + noexcept(std::is_nothrow_default_constructible<_Base>::value) +#endif + : _Base() { } + // 21.3.1 construct/copy/destroy: - explicit basic_string(const _Allocator& __a = _Allocator()) - // _GLIBCXX_NOEXCEPT + explicit + basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus < 201103L @@ -90,7 +97,19 @@ namespace __gnu_debug : _Base(__l, __a) { } +#if _GLIBCXX_USE_CXX11_ABI + basic_string(const basic_string& __s, const _Allocator& __a) + : _Base(__s, __a) { } + + basic_string(basic_string&& __s, const _Allocator& __a) + : _Base(std::move(__s), __a) { } +#endif + ~basic_string() = default; + + // Provides conversion from a normal-mode string to a debug-mode string + basic_string(_Base&& __base) noexcept + : _Base(std::move(__base)) { } #endif // C++11 // Provides conversion from a normal-mode string to a debug-mode string @@ -277,7 +296,7 @@ namespace __gnu_debug reference operator[](size_type __pos) // _GLIBCXX_NOEXCEPT { -#ifdef _GLIBCXX_DEBUG_PEDANTIC +#if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC) __glibcxx_check_subscript(__pos); #else // as an extension v3 allows s[s.size()] when s is non-const. @@ -406,6 +425,7 @@ namespace __gnu_debug #if __cplusplus >= 201103L basic_string& assign(basic_string&& __x) + noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x)))) { _Base::assign(std::move(__x)); this->_M_invalidate_all(); @@ -701,6 +721,9 @@ namespace __gnu_debug void swap(basic_string& __x) +#if _GLIBCXX_USE_CXX11_ABI + _GLIBCXX_NOEXCEPT +#endif { _Safe::_M_swap(__x); _Base::swap(__x); diff --git a/contrib/gcc-5.0/libstdc++-v3/include/debug/vector b/contrib/gcc-5.0/libstdc++-v3/include/debug/vector index bf0a88eb01..085e5f73ad 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/debug/vector +++ b/contrib/gcc-5.0/libstdc++-v3/include/debug/vector @@ -37,9 +37,12 @@ namespace __gnu_debug { - /// Special vector safe base class to add a guaranteed capacity information - /// useful to detect code relying on the libstdc++ reallocation management - /// implementation detail. + /** @brief Base class for Debug Mode vector. + * + * Adds information about the guaranteed capacity, which is useful for + * detecting code which relies on non-portable implementation details of + * the libstdc++ reallocation policy. + */ template class _Safe_vector diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_dir.h b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_dir.h index 0c5253fb62..7c5f8e8ab2 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_dir.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_dir.h @@ -153,8 +153,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 }; struct _Dir; + class directory_iterator; class recursive_directory_iterator; + struct __directory_iterator_proxy + { + const directory_entry& operator*() const& noexcept { return _M_entry; } + + directory_entry operator*() && noexcept { return std::move(_M_entry); } + + private: + friend class directory_iterator; + friend class recursive_directory_iterator; + + explicit + __directory_iterator_proxy(const directory_entry& __e) : _M_entry(__e) { } + + directory_entry _M_entry; + }; + class directory_iterator { public: @@ -177,7 +194,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 : directory_iterator(__p, directory_options::none, __ec) { } directory_iterator(const path& __p, - directory_options __options, error_code& __ec) noexcept + directory_options __options, + error_code& __ec) noexcept : directory_iterator(__p, __options, &__ec) { } directory_iterator(const directory_iterator& __rhs) = default; @@ -186,19 +204,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ~directory_iterator() = default; - directory_iterator& operator=(const directory_iterator& __rhs) = default; - directory_iterator& operator=(directory_iterator&& __rhs) noexcept = default; + directory_iterator& + operator=(const directory_iterator& __rhs) = default; + + directory_iterator& + operator=(directory_iterator&& __rhs) noexcept = default; const directory_entry& operator*() const; const directory_entry* operator->() const { return &**this; } directory_iterator& operator++(); directory_iterator& increment(error_code& __ec) noexcept; - directory_iterator operator++(int) + __directory_iterator_proxy operator++(int) { - auto __tmp = *this; + __directory_iterator_proxy __pr{**this}; ++*this; - return __tmp; + return __pr; } private: @@ -214,10 +235,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 }; inline directory_iterator - begin(directory_iterator __iter) { return __iter; } + begin(directory_iterator __iter) noexcept + { return __iter; } inline directory_iterator - end(directory_iterator) { return directory_iterator(); } + end(directory_iterator) noexcept + { return directory_iterator(); } inline bool operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) @@ -274,18 +297,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 // modifiers recursive_directory_iterator& - operator=(const recursive_directory_iterator& __rhs) noexcept; + operator=(const recursive_directory_iterator& __rhs) noexcept; recursive_directory_iterator& - operator=(recursive_directory_iterator&& __rhs) noexcept; + operator=(recursive_directory_iterator&& __rhs) noexcept; recursive_directory_iterator& operator++(); recursive_directory_iterator& increment(error_code& __ec) noexcept; - recursive_directory_iterator operator++(int) + __directory_iterator_proxy operator++(int) { - auto __tmp = *this; + __directory_iterator_proxy __pr{**this}; ++*this; - return __tmp; + return __pr; } void pop(); @@ -301,15 +324,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 struct _Dir_stack; std::shared_ptr<_Dir_stack> _M_dirs; - directory_options _M_options; - bool _M_pending; + directory_options _M_options = {}; + bool _M_pending = false; }; inline recursive_directory_iterator - begin(recursive_directory_iterator __iter) { return __iter; } + begin(recursive_directory_iterator __iter) noexcept + { return __iter; } inline recursive_directory_iterator - end(recursive_directory_iterator) { return recursive_directory_iterator(); } + end(recursive_directory_iterator) noexcept + { return recursive_directory_iterator(); } inline bool operator==(const recursive_directory_iterator& __lhs, diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_fwd.h b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_fwd.h index a5ed2c5de0..9cf903fe90 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_fwd.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_fwd.h @@ -22,8 +22,9 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . -/** @file experimental/filesystem - * This is a TS C++ Library header. +/** @file experimental/fs_fwd.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{experimental/filesystem} */ #ifndef _GLIBCXX_EXPERIMENTAL_FS_FWD_H @@ -52,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif /** - * @defgroup filesystem + * @defgroup filesystem Filesystem * @ingroup experimental * * Utilities for performing operations on file systems and their components, @@ -92,7 +93,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 }; constexpr copy_options - operator&(copy_options __x, copy_options __y) + operator&(copy_options __x, copy_options __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -100,7 +101,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr copy_options - operator|(copy_options __x, copy_options __y) + operator|(copy_options __x, copy_options __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -108,7 +109,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr copy_options - operator^(copy_options __x, copy_options __y) + operator^(copy_options __x, copy_options __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -116,22 +117,22 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr copy_options - operator~(copy_options __x) + operator~(copy_options __x) noexcept { using __utype = typename std::underlying_type::type; return static_cast(~static_cast<__utype>(__x)); } inline copy_options& - operator&=(copy_options& __x, copy_options __y) + operator&=(copy_options& __x, copy_options __y) noexcept { return __x = __x & __y; } inline copy_options& - operator|=(copy_options& __x, copy_options __y) + operator|=(copy_options& __x, copy_options __y) noexcept { return __x = __x | __y; } inline copy_options& - operator^=(copy_options& __x, copy_options __y) + operator^=(copy_options& __x, copy_options __y) noexcept { return __x = __x ^ __y; } @@ -162,7 +163,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 }; constexpr perms - operator&(perms __x, perms __y) + operator&(perms __x, perms __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -170,7 +171,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr perms - operator|(perms __x, perms __y) + operator|(perms __x, perms __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -178,7 +179,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr perms - operator^(perms __x, perms __y) + operator^(perms __x, perms __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -186,22 +187,22 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr perms - operator~(perms __x) + operator~(perms __x) noexcept { using __utype = typename std::underlying_type::type; return static_cast(~static_cast<__utype>(__x)); } inline perms& - operator&=(perms& __x, perms __y) + operator&=(perms& __x, perms __y) noexcept { return __x = __x & __y; } inline perms& - operator|=(perms& __x, perms __y) + operator|=(perms& __x, perms __y) noexcept { return __x = __x | __y; } inline perms& - operator^=(perms& __x, perms __y) + operator^=(perms& __x, perms __y) noexcept { return __x = __x ^ __y; } // Bitmask type @@ -210,7 +211,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 }; constexpr directory_options - operator&(directory_options __x, directory_options __y) + operator&(directory_options __x, directory_options __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -218,7 +219,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr directory_options - operator|(directory_options __x, directory_options __y) + operator|(directory_options __x, directory_options __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -226,7 +227,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr directory_options - operator^(directory_options __x, directory_options __y) + operator^(directory_options __x, directory_options __y) noexcept { using __utype = typename std::underlying_type::type; return static_cast( @@ -234,22 +235,22 @@ _GLIBCXX_END_NAMESPACE_CXX11 } constexpr directory_options - operator~(directory_options __x) + operator~(directory_options __x) noexcept { using __utype = typename std::underlying_type::type; return static_cast(~static_cast<__utype>(__x)); } inline directory_options& - operator&=(directory_options& __x, directory_options __y) + operator&=(directory_options& __x, directory_options __y) noexcept { return __x = __x & __y; } inline directory_options& - operator|=(directory_options& __x, directory_options __y) + operator|=(directory_options& __x, directory_options __y) noexcept { return __x = __x | __y; } inline directory_options& - operator^=(directory_options& __x, directory_options __y) + operator^=(directory_options& __x, directory_options __y) noexcept { return __x = __x ^ __y; } typedef chrono::time_point file_time_type; diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_ops.h b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_ops.h index 6b7d4709ee..91b890203f 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_ops.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_ops.h @@ -22,8 +22,9 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . -/** @file experimental/filesystem - * This is a TS C++ Library header. +/** @file experimental/fs_fwd.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{experimental/filesystem} */ #ifndef _GLIBCXX_EXPERIMENTAL_FS_OPS_H diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_path.h b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_path.h index 1632a7e992..176918a394 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_path.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/fs_path.h @@ -549,16 +549,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 std::string _M_what = _M_gen_what(); }; - struct path::_Cmpt : path - { - _Cmpt(string_type __s, _Type __t, size_t __pos) - : path(std::move(__s), __t), _M_pos(__pos) { } - - _Cmpt() : _M_pos(-1) { } - - size_t _M_pos; - }; - template<> struct path::__is_encoded_char : std::true_type { using value_type = char; }; @@ -575,6 +565,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 struct path::__is_encoded_char : std::true_type { using value_type = char32_t; }; + struct path::_Cmpt : path + { + _Cmpt(string_type __s, _Type __t, size_t __pos) + : path(std::move(__s), __t), _M_pos(__pos) { } + + _Cmpt() : _M_pos(-1) { } + + size_t _M_pos; + }; + // specialize _Cvt for degenerate 'noconv' case template<> struct path::_Cvt diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/optional b/contrib/gcc-5.0/libstdc++-v3/include/experimental/optional index 811235bfce..f6e3fa0258 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/optional +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/optional @@ -33,6 +33,12 @@ * @defgroup experimental Experimental * * Components specified by various Technical Specifications. + * + * As indicated by the std::experimental namespace and the header paths, + * the contents of these Technical Specifications are experimental and not + * part of the C++ standard. As such the interfaces and implementations may + * change in the future, and there is no guarantee of compatibility + * between different GCC releases for these features. */ #if __cplusplus <= 201103L diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view b/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view index 9c2b773573..f11a1878c5 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view @@ -23,7 +23,7 @@ // . /** @file experimental/string_view - * This is a Standard C++ Library header. + * This is a TS C++ Library header. */ // diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view.tcc b/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view.tcc index 75a34f90b2..942184206a 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view.tcc +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/string_view.tcc @@ -24,7 +24,7 @@ /** @file experimental/string_view.tcc * This is an internal header file, included by other library headers. - * Do not attempt to use it directly. @headername{string_view} + * Do not attempt to use it directly. @headername{experimental/string_view} */ // diff --git a/contrib/gcc-5.0/libstdc++-v3/include/experimental/tuple b/contrib/gcc-5.0/libstdc++-v3/include/experimental/tuple index 4baede4af5..99935f1233 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/experimental/tuple +++ b/contrib/gcc-5.0/libstdc++-v3/include/experimental/tuple @@ -54,7 +54,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr decltype(auto) __apply_impl(_Fn&& f, _Tuple&& t, std::index_sequence<_Idx...>) - { return std::forward<_Fn>(f)(get<_Idx>(forward<_Tuple>(t))...); } + { + return std::forward<_Fn>(f)(std::get<_Idx>(std::forward<_Tuple>(t))...); + } template constexpr decltype(auto) diff --git a/contrib/gcc-5.0/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp b/contrib/gcc-5.0/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp index da01e1a2d4..674fa92012 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp +++ b/contrib/gcc-5.0/libstdc++-v3/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp @@ -166,13 +166,8 @@ namespace __gnu_pbds class Node_Update, class Node, typename _Alloc> - struct bin_search_tree_traits< - Key, - null_type, - Cmp_Fn, - Node_Update, - Node, - _Alloc> + struct + bin_search_tree_traits { private: typedef types_traits type_traits; diff --git a/contrib/gcc-5.0/libstdc++-v3/include/std/bitset b/contrib/gcc-5.0/libstdc++-v3/include/std/bitset index d6be839bd7..44df60c115 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/std/bitset +++ b/contrib/gcc-5.0/libstdc++-v3/include/std/bitset @@ -663,7 +663,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER }; #if __cplusplus >= 201103L - template + template struct _Sanitize_val { static constexpr unsigned long long @@ -681,8 +681,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif /** - * @class bitset - * * @brief The %bitset class represents a @e fixed-size sequence of bits. * @ingroup utilities * diff --git a/contrib/gcc-5.0/libstdc++-v3/include/std/functional b/contrib/gcc-5.0/libstdc++-v3/include/std/functional index e9d48e4087..90dc36fa1f 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/std/functional +++ b/contrib/gcc-5.0/libstdc++-v3/include/std/functional @@ -1122,7 +1122,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) // Call unqualified template()( + = decltype( std::declval<_Functor&>()( _Mu<_Bound_args>()( std::declval<_Bound_args&>(), std::declval&>() )... ) )> _Result @@ -1136,7 +1136,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) // Call as const template= 0), - typename add_const<_Functor>::type>::type>()( + typename add_const<_Functor>::type&>::type>()( _Mu<_Bound_args>()( std::declval(), std::declval&>() )... ) )> _Result @@ -1150,7 +1150,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) // Call as volatile template= 0), - typename add_volatile<_Functor>::type>::type>()( + typename add_volatile<_Functor>::type&>::type>()( _Mu<_Bound_args>()( std::declval(), std::declval&>() )... ) )> _Result @@ -1164,7 +1164,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) // Call as const volatile template= 0), - typename add_cv<_Functor>::type>::type>()( + typename add_cv<_Functor>::type&>::type>()( _Mu<_Bound_args>()( std::declval(), std::declval&>() )... ) )> _Result @@ -1764,13 +1764,13 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) template static bool - _M_not_empty_function(_Tp* const& __fp) - { return __fp; } + _M_not_empty_function(_Tp* __fp) + { return __fp != nullptr; } template static bool - _M_not_empty_function(_Tp _Class::* const& __mp) - { return __mp; } + _M_not_empty_function(_Tp _Class::* __mp) + { return __mp != nullptr; } template static bool @@ -1883,7 +1883,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) static _Res _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) { - return __callable_functor(**_Base::_M_get_pointer(__functor))( + return std::__callable_functor(**_Base::_M_get_pointer(__functor))( std::forward<_ArgTypes>(__args)...); } }; @@ -1898,7 +1898,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) static void _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) { - __callable_functor(**_Base::_M_get_pointer(__functor))( + std::__callable_functor(**_Base::_M_get_pointer(__functor))( std::forward<_ArgTypes>(__args)...); } }; @@ -1977,19 +1977,14 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) { typedef _Res _Signature_type(_ArgTypes...); - template - using _Invoke = decltype(__callable_functor(std::declval<_Functor&>()) - (std::declval<_ArgTypes>()...) ); + template::type> + struct _Callable : __check_func_return_type<_Res2, _Res> { }; // Used so the return type convertibility checks aren't done when // performing overload resolution for copy construction/assignment. template - using _NotSelf = __not_>; - - template - using _Callable - = __and_<_NotSelf<_Functor>, - __check_func_return_type<_Invoke<_Functor>, _Res>>; + struct _Callable : false_type { }; template using _Requires = typename enable_if<_Cond::value, _Tp>::type; @@ -2054,6 +2049,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) * reference_wrapper, this function will not throw. */ template>, void>, typename = _Requires<_Callable<_Functor>, void>> function(_Functor); @@ -2246,7 +2242,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) } template - template + template function<_Res(_ArgTypes...)>:: function(_Functor __f) : _Function_base() diff --git a/contrib/gcc-5.0/libstdc++-v3/include/std/mutex b/contrib/gcc-5.0/libstdc++-v3/include/std/mutex index deb85dfefe..b80a8a0123 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/std/mutex +++ b/contrib/gcc-5.0/libstdc++-v3/include/std/mutex @@ -114,7 +114,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - /// mutex + /// The standard mutex type. class mutex : private __mutex_base { public: @@ -158,7 +158,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return &_M_mutex; } }; - /// recursive_mutex + /// The standard recursive mutex type. class recursive_mutex : private __recursive_mutex_base { public: @@ -243,7 +243,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; - /// timed_mutex + /// The standard timed mutex type. class timed_mutex : private __mutex_base, public __timed_mutex_impl { @@ -295,7 +295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return &_M_mutex; } }; - /// recursive_timed_mutex + /// The standard recursive timed mutex type. class recursive_timed_mutex : private __recursive_mutex_base, public __timed_mutex_impl @@ -360,13 +360,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// and manage it. struct adopt_lock_t { }; + /// Tag used to prevent a scoped lock from acquiring ownership of a mutex. constexpr defer_lock_t defer_lock { }; + + /// Tag used to prevent a scoped lock from blocking if a mutex is locked. constexpr try_to_lock_t try_to_lock { }; + + /// Tag used to make a scoped lock take ownership of a locked mutex. constexpr adopt_lock_t adopt_lock { }; - /// @brief Scoped lock idiom. - // Acquire the mutex here with a constructor call, then release with - // the destructor call in accordance with RAII style. + /** @brief A movable scoped lock type. + * + * A unique_lock controls mutex ownership within a scope. Ownership of the + * mutex can be delayed until after construction and can be transferred + * to another unique_lock by move construction or move assignment. If a + * mutex lock is owned when the destructor runs ownership will be released. + */ template class lock_guard { diff --git a/contrib/gcc-5.0/libstdc++-v3/include/tr2/dynamic_bitset b/contrib/gcc-5.0/libstdc++-v3/include/tr2/dynamic_bitset index 183179f25d..77bddc32b9 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/tr2/dynamic_bitset +++ b/contrib/gcc-5.0/libstdc++-v3/include/tr2/dynamic_bitset @@ -593,6 +593,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __str A string of '0' and '1' characters. * @param __pos Index of the first character in @p __str to use. * @param __n The number of characters to copy. + * @param __zero The character to use for unset bits. + * @param __one The character to use for set bits. + * @param __alloc An allocator. * @throw std::out_of_range If @p __pos is bigger the size of @p __str. * @throw std::invalid_argument If a character appears in the string * which is neither '0' nor '1'. 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 a454064ce6..8cd8eb46a9 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 @@ -789,7 +789,11 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end, { range from{ __from, __from_end }; range to{ __to, __to_end }; - auto res = ucs2_in(from, to, _M_maxcode, _M_mode); + codecvt_mode mode = codecvt_mode(_M_mode & (consume_header|generate_header)); +#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ + mode = codecvt_mode(mode | little_endian); +#endif + auto res = ucs2_in(from, to, _M_maxcode, mode); __from_next = from.next; __to_next = to.next; return res; @@ -1264,7 +1268,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end, { range from{ __from, __from_end }; range to{ __to, __to_end }; - codecvt_mode mode = codecvt_mode(_M_mode | (consume_header|generate_header)); + codecvt_mode mode = codecvt_mode(_M_mode & (consume_header|generate_header)); #if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ mode = codecvt_mode(mode | little_endian); #endif diff --git a/contrib/gcc-5.0/libstdc++-v3/src/c++11/futex.cc b/contrib/gcc-5.0/libstdc++-v3/src/c++11/futex.cc index e04dba812b..e723364ced 100644 --- a/contrib/gcc-5.0/libstdc++-v3/src/c++11/futex.cc +++ b/contrib/gcc-5.0/libstdc++-v3/src/c++11/futex.cc @@ -52,7 +52,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // we will fall back to spin-waiting. The only thing we could do // here on errors is abort. int ret __attribute__((unused)); - ret = syscall (SYS_futex, __addr, futex_wait_op, __val); + ret = syscall (SYS_futex, __addr, futex_wait_op, __val, nullptr); _GLIBCXX_DEBUG_ASSERT(ret == 0 || errno == EINTR || errno == EAGAIN); return true; } 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 906cafa735..7fa415b49d 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 @@ -70,9 +70,9 @@ static inline int get_nprocs() namespace std _GLIBCXX_VISIBILITY(default) { - namespace + extern "C" { - extern "C" void* + static void* execute_native_thread_routine(void* __p) { thread::_Impl_base* __t = static_cast(__p); @@ -94,7 +94,7 @@ namespace std _GLIBCXX_VISIBILITY(default) return nullptr; } - } + } // extern "C" _GLIBCXX_BEGIN_NAMESPACE_VERSION -- 2.41.0