From 58e805e64ba1cecf4e203f4573319a183d9c0088 Mon Sep 17 00:00:00 2001 From: zrj Date: Tue, 16 Apr 2019 05:37:34 +0300 Subject: [PATCH] Update GCC80 to version 8.3 --- contrib/gcc-8.0/LAST_UPDATED | 2 +- contrib/gcc-8.0/gcc/BASE-VER | 2 +- contrib/gcc-8.0/gcc/asan.c | 2 +- contrib/gcc-8.0/gcc/asan.h | 2 + contrib/gcc-8.0/gcc/attribs.c | 2 + contrib/gcc-8.0/gcc/bb-reorder.c | 136 ++++-- contrib/gcc-8.0/gcc/c-family/c-ada-spec.c | 14 +- contrib/gcc-8.0/gcc/c-family/c-attribs.c | 31 +- contrib/gcc-8.0/gcc/c-family/c-common.c | 30 +- contrib/gcc-8.0/gcc/c-family/c-common.h | 4 +- contrib/gcc-8.0/gcc/c-family/c-cppbuiltin.c | 4 + contrib/gcc-8.0/gcc/c-family/c-omp.c | 15 +- contrib/gcc-8.0/gcc/c-family/c-opts.c | 53 ++- contrib/gcc-8.0/gcc/c-family/c-ubsan.c | 6 +- contrib/gcc-8.0/gcc/c-family/c-warn.c | 19 +- contrib/gcc-8.0/gcc/c-family/c.opt | 4 +- contrib/gcc-8.0/gcc/c/c-convert.c | 1 + contrib/gcc-8.0/gcc/c/c-decl.c | 31 +- contrib/gcc-8.0/gcc/c/c-fold.c | 2 +- contrib/gcc-8.0/gcc/c/c-parser.c | 122 ++++-- contrib/gcc-8.0/gcc/c/c-tree.h | 5 +- contrib/gcc-8.0/gcc/c/c-typeck.c | 106 ++++- contrib/gcc-8.0/gcc/calls.c | 287 +++++++++---- contrib/gcc-8.0/gcc/cfgcleanup.c | 7 +- contrib/gcc-8.0/gcc/cfgexpand.c | 46 +- contrib/gcc-8.0/gcc/cfgrtl.c | 66 ++- contrib/gcc-8.0/gcc/cgraph.c | 7 +- contrib/gcc-8.0/gcc/cgraph.h | 4 + contrib/gcc-8.0/gcc/cgraphunit.c | 2 +- contrib/gcc-8.0/gcc/collect2.c | 41 +- contrib/gcc-8.0/gcc/combine.c | 52 ++- contrib/gcc-8.0/gcc/common.opt | 10 +- .../gcc/common/config/i386/i386-common.c | 9 +- .../gcc/config/i386/avx512bitalgintrin.h | 2 +- .../gcc-8.0/gcc/config/i386/avx512bwintrin.h | 4 +- .../gcc-8.0/gcc/config/i386/avx512fintrin.h | 20 +- .../gcc/config/i386/avx512vbmi2vlintrin.h | 4 +- .../gcc/config/i386/avx512vlbwintrin.h | 182 ++++---- .../gcc-8.0/gcc/config/i386/avx512vlintrin.h | 20 +- contrib/gcc-8.0/gcc/config/i386/emmintrin.h | 7 +- .../gcc-8.0/gcc/config/i386/i386-builtin.def | 2 +- contrib/gcc-8.0/gcc/config/i386/i386.c | 233 +++++++---- contrib/gcc-8.0/gcc/config/i386/i386.h | 14 +- contrib/gcc-8.0/gcc/config/i386/i386.md | 95 ++++- contrib/gcc-8.0/gcc/config/i386/predicates.md | 4 +- contrib/gcc-8.0/gcc/config/i386/sse.md | 262 +++++++----- .../gcc/config/i386/vpclmulqdqintrin.h | 6 +- contrib/gcc-8.0/gcc/config/i386/x86-tune.def | 26 +- contrib/gcc-8.0/gcc/config/i386/xsaveintrin.h | 2 +- contrib/gcc-8.0/gcc/coverage.c | 11 +- contrib/gcc-8.0/gcc/cp/call.c | 21 +- contrib/gcc-8.0/gcc/cp/class.c | 50 ++- contrib/gcc-8.0/gcc/cp/constexpr.c | 53 ++- contrib/gcc-8.0/gcc/cp/cp-gimplify.c | 40 +- contrib/gcc-8.0/gcc/cp/cp-tree.h | 14 +- contrib/gcc-8.0/gcc/cp/cvt.c | 5 +- contrib/gcc-8.0/gcc/cp/decl.c | 67 ++- contrib/gcc-8.0/gcc/cp/decl2.c | 34 +- contrib/gcc-8.0/gcc/cp/error.c | 9 +- contrib/gcc-8.0/gcc/cp/expr.c | 11 + contrib/gcc-8.0/gcc/cp/init.c | 41 +- contrib/gcc-8.0/gcc/cp/lambda.c | 73 +++- contrib/gcc-8.0/gcc/cp/method.c | 14 +- contrib/gcc-8.0/gcc/cp/name-lookup.c | 54 ++- contrib/gcc-8.0/gcc/cp/optimize.c | 25 +- contrib/gcc-8.0/gcc/cp/parser.c | 172 +++++--- contrib/gcc-8.0/gcc/cp/pt.c | 180 ++++++-- contrib/gcc-8.0/gcc/cp/search.c | 18 +- contrib/gcc-8.0/gcc/cp/semantics.c | 41 +- contrib/gcc-8.0/gcc/cp/tree.c | 98 ++++- contrib/gcc-8.0/gcc/cp/typeck.c | 38 +- contrib/gcc-8.0/gcc/cp/typeck2.c | 9 +- contrib/gcc-8.0/gcc/dce.c | 29 +- contrib/gcc-8.0/gcc/defaults.h | 4 + contrib/gcc-8.0/gcc/diagnostic-show-locus.c | 2 +- contrib/gcc-8.0/gcc/diagnostic.c | 3 +- contrib/gcc-8.0/gcc/dojump.c | 16 +- contrib/gcc-8.0/gcc/dwarf2out.c | 229 ++++++++-- contrib/gcc-8.0/gcc/except.c | 4 + contrib/gcc-8.0/gcc/expmed.c | 30 +- contrib/gcc-8.0/gcc/expr.c | 130 ++++-- contrib/gcc-8.0/gcc/expr.h | 3 +- contrib/gcc-8.0/gcc/final.c | 9 +- contrib/gcc-8.0/gcc/fold-const.c | 51 ++- contrib/gcc-8.0/gcc/function-tests.c | 1 + contrib/gcc-8.0/gcc/function.c | 2 +- contrib/gcc-8.0/gcc/gcov.c | 15 +- contrib/gcc-8.0/gcc/gcse.c | 21 +- contrib/gcc-8.0/gcc/genmatch.c | 10 +- contrib/gcc-8.0/gcc/gimple-fold.c | 9 +- .../gcc-8.0/gcc/gimple-loop-interchange.cc | 7 +- contrib/gcc-8.0/gcc/gimple-loop-jam.c | 32 +- contrib/gcc-8.0/gcc/gimple-match-head.c | 43 ++ contrib/gcc-8.0/gcc/gimple-pretty-print.c | 2 + contrib/gcc-8.0/gcc/gimple-ssa-backprop.c | 31 +- .../gcc-8.0/gcc/gimple-ssa-isolate-paths.c | 4 +- contrib/gcc-8.0/gcc/gimple-ssa-sprintf.c | 94 +++-- .../gcc-8.0/gcc/gimple-ssa-store-merging.c | 154 ++++++- .../gcc/gimple-ssa-strength-reduction.c | 240 ++++++----- contrib/gcc-8.0/gcc/gimple.h | 26 +- contrib/gcc-8.0/gcc/gimplify.c | 118 +++++- contrib/gcc-8.0/gcc/graphite.h | 2 + contrib/gcc-8.0/gcc/ipa-cp.c | 6 +- contrib/gcc-8.0/gcc/ipa-devirt.c | 8 +- contrib/gcc-8.0/gcc/ipa-icf-gimple.c | 3 + contrib/gcc-8.0/gcc/ipa-icf.c | 27 +- contrib/gcc-8.0/gcc/ipa-icf.h | 3 + contrib/gcc-8.0/gcc/ipa-inline.c | 10 +- contrib/gcc-8.0/gcc/ipa-polymorphic-call.c | 32 +- contrib/gcc-8.0/gcc/ipa-prop.c | 3 +- contrib/gcc-8.0/gcc/ipa-pure-const.c | 4 +- contrib/gcc-8.0/gcc/ipa-reference.c | 2 +- contrib/gcc-8.0/gcc/ipa-utils.c | 43 +- contrib/gcc-8.0/gcc/ipa-utils.h | 2 +- contrib/gcc-8.0/gcc/ipa-visibility.c | 3 +- contrib/gcc-8.0/gcc/ipa.c | 12 +- contrib/gcc-8.0/gcc/langhooks.c | 2 +- contrib/gcc-8.0/gcc/lower-subreg.c | 11 +- contrib/gcc-8.0/gcc/lra.c | 4 +- contrib/gcc-8.0/gcc/lto-cgraph.c | 10 +- contrib/gcc-8.0/gcc/lto-opts.c | 15 + contrib/gcc-8.0/gcc/lto-streamer-out.c | 1 - contrib/gcc-8.0/gcc/lto-streamer.h | 2 +- contrib/gcc-8.0/gcc/lto-wrapper.c | 111 ++++- contrib/gcc-8.0/gcc/lto/lto-partition.c | 190 ++++++--- contrib/gcc-8.0/gcc/lto/lto-symtab.c | 5 +- contrib/gcc-8.0/gcc/lto/lto.c | 49 +-- contrib/gcc-8.0/gcc/match.pd | 25 +- contrib/gcc-8.0/gcc/omp-expand.c | 88 ++-- contrib/gcc-8.0/gcc/omp-low.c | 35 +- contrib/gcc-8.0/gcc/omp-simd-clone.c | 30 +- contrib/gcc-8.0/gcc/optabs.c | 34 +- contrib/gcc-8.0/gcc/optc-save-gen.awk | 10 +- contrib/gcc-8.0/gcc/opth-gen.awk | 3 +- contrib/gcc-8.0/gcc/opts.c | 11 +- contrib/gcc-8.0/gcc/passes.c | 4 +- contrib/gcc-8.0/gcc/pretty-print.c | 42 +- contrib/gcc-8.0/gcc/pretty-print.h | 14 +- contrib/gcc-8.0/gcc/profile-count.h | 12 +- contrib/gcc-8.0/gcc/profile.c | 250 ++++++----- contrib/gcc-8.0/gcc/regcprop.c | 6 + contrib/gcc-8.0/gcc/regrename.c | 19 +- contrib/gcc-8.0/gcc/rtl.h | 22 + contrib/gcc-8.0/gcc/rtlanal.c | 30 +- contrib/gcc-8.0/gcc/stor-layout.c | 21 +- contrib/gcc-8.0/gcc/store-motion.c | 4 +- contrib/gcc-8.0/gcc/symtab.c | 19 +- contrib/gcc-8.0/gcc/tracer.c | 28 +- contrib/gcc-8.0/gcc/tree-cfg.c | 51 ++- contrib/gcc-8.0/gcc/tree-chrec.c | 10 +- contrib/gcc-8.0/gcc/tree-complex.c | 24 +- contrib/gcc-8.0/gcc/tree-core.h | 5 +- contrib/gcc-8.0/gcc/tree-data-ref.c | 23 +- contrib/gcc-8.0/gcc/tree-dump.c | 4 - contrib/gcc-8.0/gcc/tree-inline.c | 42 +- contrib/gcc-8.0/gcc/tree-loop-distribution.c | 8 +- contrib/gcc-8.0/gcc/tree-predcom.c | 2 +- contrib/gcc-8.0/gcc/tree-profile.c | 28 +- contrib/gcc-8.0/gcc/tree-ssa-alias.c | 2 +- contrib/gcc-8.0/gcc/tree-ssa-ccp.c | 2 +- contrib/gcc-8.0/gcc/tree-ssa-coalesce.c | 107 +---- contrib/gcc-8.0/gcc/tree-ssa-copy.c | 2 +- contrib/gcc-8.0/gcc/tree-ssa-dom.c | 3 +- contrib/gcc-8.0/gcc/tree-ssa-loop-ivcanon.c | 4 +- contrib/gcc-8.0/gcc/tree-ssa-loop-split.c | 3 +- contrib/gcc-8.0/gcc/tree-ssa-math-opts.c | 12 +- contrib/gcc-8.0/gcc/tree-ssa-phiprop.c | 10 +- contrib/gcc-8.0/gcc/tree-ssa-propagate.c | 165 ++++---- contrib/gcc-8.0/gcc/tree-ssa-propagate.h | 2 - contrib/gcc-8.0/gcc/tree-ssa-reassoc.c | 11 +- contrib/gcc-8.0/gcc/tree-ssa-sccvn.c | 52 ++- contrib/gcc-8.0/gcc/tree-ssa-strlen.c | 55 ++- contrib/gcc-8.0/gcc/tree-ssa-strlen.h | 1 + contrib/gcc-8.0/gcc/tree-ssa-structalias.c | 17 +- contrib/gcc-8.0/gcc/tree-ssa-tail-merge.c | 31 +- contrib/gcc-8.0/gcc/tree-ssa-threadupdate.c | 4 +- contrib/gcc-8.0/gcc/tree-ssa-uncprop.c | 23 +- contrib/gcc-8.0/gcc/tree-ssa.c | 1 + contrib/gcc-8.0/gcc/tree-streamer-in.c | 7 + contrib/gcc-8.0/gcc/tree-streamer-out.c | 18 +- contrib/gcc-8.0/gcc/tree-switch-conversion.c | 78 ++-- contrib/gcc-8.0/gcc/tree-vect-data-refs.c | 26 +- contrib/gcc-8.0/gcc/tree-vect-generic.c | 18 +- contrib/gcc-8.0/gcc/tree-vect-loop.c | 55 ++- contrib/gcc-8.0/gcc/tree-vect-slp.c | 51 ++- contrib/gcc-8.0/gcc/tree-vect-stmts.c | 50 ++- contrib/gcc-8.0/gcc/tree-vectorizer.h | 60 +-- contrib/gcc-8.0/gcc/tree-vrp.c | 13 +- contrib/gcc-8.0/gcc/tree.c | 18 +- contrib/gcc-8.0/gcc/tree.h | 7 + contrib/gcc-8.0/gcc/valtrack.c | 2 - contrib/gcc-8.0/gcc/value-prof.c | 2 +- contrib/gcc-8.0/gcc/value-prof.h | 3 +- contrib/gcc-8.0/gcc/var-tracking.c | 18 + contrib/gcc-8.0/gcc/varasm.c | 56 ++- contrib/gcc-8.0/gcc/varpool.c | 10 +- contrib/gcc-8.0/gcc/vr-values.c | 8 +- contrib/gcc-8.0/libbacktrace/elf.c | 2 +- contrib/gcc-8.0/libgcc/config/i386/cpuinfo.c | 11 +- contrib/gcc-8.0/libgcc/unwind-dw2.c | 2 +- contrib/gcc-8.0/libiberty/simple-object-elf.c | 4 + contrib/gcc-8.0/libiberty/simple-object.c | 6 +- .../libstdc++-v3/include/bits/alloc_traits.h | 7 +- .../libstdc++-v3/include/bits/basic_string.h | 73 +++- .../include/bits/basic_string.tcc | 25 +- .../libstdc++-v3/include/bits/c++config | 5 + .../libstdc++-v3/include/bits/char_traits.h | 6 +- .../include/bits/cpp_type_traits.h | 11 + .../libstdc++-v3/include/bits/forward_list.h | 13 +- .../include/bits/forward_list.tcc | 8 +- .../libstdc++-v3/include/bits/fs_dir.h | 14 +- .../libstdc++-v3/include/bits/fs_path.h | 50 +-- .../libstdc++-v3/include/bits/hashtable.h | 3 + .../libstdc++-v3/include/bits/locale_conv.h | 8 +- .../libstdc++-v3/include/bits/locale_facets.h | 12 +- .../libstdc++-v3/include/bits/node_handle.h | 2 +- .../libstdc++-v3/include/bits/quoted_string.h | 20 +- .../libstdc++-v3/include/bits/random.tcc | 4 +- .../gcc-8.0/libstdc++-v3/include/bits/regex.h | 42 ++ .../include/bits/regex_automaton.h | 2 +- .../include/bits/regex_compiler.tcc | 4 +- .../include/bits/regex_executor.tcc | 4 +- .../libstdc++-v3/include/bits/shared_ptr.h | 9 +- .../include/bits/shared_ptr_base.h | 90 ++-- .../libstdc++-v3/include/bits/stl_bvector.h | 4 +- .../libstdc++-v3/include/bits/stl_iterator.h | 5 +- .../libstdc++-v3/include/bits/stl_list.h | 3 +- .../libstdc++-v3/include/bits/stl_map.h | 21 +- .../libstdc++-v3/include/bits/stl_multimap.h | 20 +- .../libstdc++-v3/include/bits/stl_pair.h | 21 +- .../libstdc++-v3/include/bits/stl_queue.h | 38 ++ .../libstdc++-v3/include/bits/stl_stack.h | 12 + .../libstdc++-v3/include/bits/stl_vector.h | 19 +- .../libstdc++-v3/include/bits/unique_ptr.h | 8 +- .../libstdc++-v3/include/bits/unordered_map.h | 33 +- .../include/bits/valarray_array.h | 19 +- .../libstdc++-v3/include/bits/vector.tcc | 25 +- .../gcc-8.0/libstdc++-v3/include/debug/map.h | 1 + .../libstdc++-v3/include/debug/multimap.h | 1 + .../libstdc++-v3/include/debug/multiset.h | 1 + .../gcc-8.0/libstdc++-v3/include/debug/set.h | 1 + .../gcc-8.0/libstdc++-v3/include/debug/string | 2 +- .../include/experimental/algorithm | 21 +- .../include/experimental/memory_resource | 68 +-- .../libstdc++-v3/include/experimental/regex | 6 +- .../libstdc++-v3/include/experimental/string | 8 +- .../include/experimental/string_view | 2 +- .../libstdc++-v3/include/ext/aligned_buffer.h | 7 +- .../libstdc++-v3/include/ext/pointer.h | 4 + .../gcc-8.0/libstdc++-v3/include/ext/random | 4 +- .../libstdc++-v3/include/ext/vstring.h | 2 +- .../gcc-8.0/libstdc++-v3/include/std/chrono | 26 +- .../libstdc++-v3/include/std/functional | 3 +- .../gcc-8.0/libstdc++-v3/include/std/iomanip | 24 +- .../gcc-8.0/libstdc++-v3/include/std/optional | 394 ++++++++---------- .../libstdc++-v3/include/std/string_view | 8 +- .../gcc-8.0/libstdc++-v3/include/std/thread | 26 +- .../libstdc++-v3/include/std/type_traits | 120 +++--- .../gcc-8.0/libstdc++-v3/include/std/utility | 4 - .../gcc-8.0/libstdc++-v3/include/std/variant | 68 ++- .../gcc-8.0/libstdc++-v3/include/tr1/cmath | 116 ++++-- .../libsupc++/cxxabi_init_exception.h | 3 + .../libstdc++-v3/libsupc++/exception_ptr.h | 24 +- .../gcc-8.0/libstdc++-v3/libsupc++/new_opa.cc | 62 ++- .../gcc-8.0/libstdc++-v3/src/c++11/codecvt.cc | 7 +- .../libstdc++-v3/src/c++11/string-inst.cc | 6 + .../libstdc++-v3/src/c++11/system_error.cc | 256 ++++++++++++ 267 files changed, 6011 insertions(+), 2804 deletions(-) diff --git a/contrib/gcc-8.0/LAST_UPDATED b/contrib/gcc-8.0/LAST_UPDATED index 5eef1f9f96..833129688b 100644 --- a/contrib/gcc-8.0/LAST_UPDATED +++ b/contrib/gcc-8.0/LAST_UPDATED @@ -1 +1 @@ -Obtained from SVN: tags/gcc_8_1_0_release revision 259830 +Obtained from SVN: tags/gcc_8_3_0_release revision 269117 diff --git a/contrib/gcc-8.0/gcc/BASE-VER b/contrib/gcc-8.0/gcc/BASE-VER index 8104cabd36..2bf50aaf17 100644 --- a/contrib/gcc-8.0/gcc/BASE-VER +++ b/contrib/gcc-8.0/gcc/BASE-VER @@ -1 +1 @@ -8.1.0 +8.3.0 diff --git a/contrib/gcc-8.0/gcc/asan.c b/contrib/gcc-8.0/gcc/asan.c index e71ab2cc71..235e219479 100644 --- a/contrib/gcc-8.0/gcc/asan.c +++ b/contrib/gcc-8.0/gcc/asan.c @@ -253,7 +253,7 @@ static tree last_alloca_addr; /* Set of variable declarations that are going to be guarded by use-after-scope sanitizer. */ -static hash_set *asan_handled_variables = NULL; +hash_set *asan_handled_variables = NULL; hash_set *asan_used_labels = NULL; diff --git a/contrib/gcc-8.0/gcc/asan.h b/contrib/gcc-8.0/gcc/asan.h index 412af22059..2f431b4f93 100644 --- a/contrib/gcc-8.0/gcc/asan.h +++ b/contrib/gcc-8.0/gcc/asan.h @@ -110,6 +110,8 @@ extern bool asan_sanitize_stack_p (void); extern bool asan_sanitize_allocas_p (void); +extern hash_set *asan_handled_variables; + /* Return TRUE if builtin with given FCODE will be intercepted by libasan. */ diff --git a/contrib/gcc-8.0/gcc/attribs.c b/contrib/gcc-8.0/gcc/attribs.c index bfadf124dc..f5f660a6a9 100644 --- a/contrib/gcc-8.0/gcc/attribs.c +++ b/contrib/gcc-8.0/gcc/attribs.c @@ -1685,6 +1685,8 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags, a function global scope, unless declared static. */ if (current_function_decl != NULL_TREE && !TREE_STATIC (node)) TREE_PUBLIC (node) = 1; + /* Clear TREE_STATIC because DECL_EXTERNAL is set. */ + TREE_STATIC (node) = 0; } if (*no_add_attrs == false) diff --git a/contrib/gcc-8.0/gcc/bb-reorder.c b/contrib/gcc-8.0/gcc/bb-reorder.c index d2b41606a1..57edde62c6 100644 --- a/contrib/gcc-8.0/gcc/bb-reorder.c +++ b/contrib/gcc-8.0/gcc/bb-reorder.c @@ -117,6 +117,7 @@ #include "fibonacci_heap.h" #include "stringpool.h" #include "attribs.h" +#include "common/common-target.h" /* The number of rounds. In most cases there will only be 4 rounds, but when partitioning hot and cold basic blocks into separate sections of @@ -1408,36 +1409,25 @@ get_uncond_jump_length (void) return length; } -/* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions. - Add a new landing pad that will just jump to the old one and split the - edges so that no EH edge crosses partitions. */ +/* Create a forwarder block to OLD_BB starting with NEW_LABEL and in the + other partition wrt OLD_BB. */ -static void -fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb) +static basic_block +create_eh_forwarder_block (rtx_code_label *new_label, basic_block old_bb) { - eh_landing_pad new_lp; - basic_block new_bb, last_bb; - rtx_insn *jump; - unsigned new_partition; - edge_iterator ei; - edge e; - - /* Generate the new landing-pad structure. */ - new_lp = gen_eh_landing_pad (old_lp->region); - new_lp->post_landing_pad = old_lp->post_landing_pad; - new_lp->landing_pad = gen_label_rtx (); - LABEL_PRESERVE_P (new_lp->landing_pad) = 1; - - /* Put appropriate instructions in new bb. */ - rtx_code_label *new_label = emit_label (new_lp->landing_pad); + /* Split OLD_BB, so that EH pads have always only incoming EH edges, + bb_has_eh_pred bbs are treated specially by DF infrastructure. */ + old_bb = split_block_after_labels (old_bb)->dest; + /* Put the new label and a jump in the new basic block. */ + rtx_insn *label = emit_label (new_label); rtx_code_label *old_label = block_label (old_bb); - jump = emit_jump_insn (targetm.gen_jump (old_label)); + rtx_insn *jump = emit_jump_insn (targetm.gen_jump (old_label)); JUMP_LABEL (jump) = old_label; - /* Create new basic block to be dest for lp. */ - last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; - new_bb = create_basic_block (new_label, jump, last_bb); + /* Create the new basic block and put it in last position. */ + basic_block last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; + basic_block new_bb = create_basic_block (label, jump, last_bb); new_bb->aux = last_bb->aux; new_bb->count = old_bb->count; last_bb->aux = new_bb; @@ -1446,14 +1436,87 @@ fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb) make_single_succ_edge (new_bb, old_bb, 0); - /* Make sure new bb is in the other partition. */ - new_partition = BB_PARTITION (old_bb); + /* Make sure the new basic block is in the other partition. */ + unsigned new_partition = BB_PARTITION (old_bb); new_partition ^= BB_HOT_PARTITION | BB_COLD_PARTITION; BB_SET_PARTITION (new_bb, new_partition); + return new_bb; +} + +/* The common landing pad in block OLD_BB has edges from both partitions. + Add a new landing pad that will just jump to the old one and split the + edges so that no EH edge crosses partitions. */ + +static void +sjlj_fix_up_crossing_landing_pad (basic_block old_bb) +{ + const unsigned lp_len = cfun->eh->lp_array->length (); + edge_iterator ei; + edge e; + + /* Generate the new common landing-pad label. */ + rtx_code_label *new_label = gen_label_rtx (); + LABEL_PRESERVE_P (new_label) = 1; + + /* Create the forwarder block. */ + basic_block new_bb = create_eh_forwarder_block (new_label, old_bb); + + /* Create the map from old to new lp index and initialize it. */ + unsigned *index_map = (unsigned *) alloca (lp_len * sizeof (unsigned)); + memset (index_map, 0, lp_len * sizeof (unsigned)); + /* Fix up the edges. */ for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; ) - if (e->src != new_bb && BB_PARTITION (e->src) == new_partition) + if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb)) + { + rtx_insn *insn = BB_END (e->src); + rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + + gcc_assert (note != NULL); + const unsigned old_index = INTVAL (XEXP (note, 0)); + + /* Generate the new landing-pad structure. */ + if (index_map[old_index] == 0) + { + eh_landing_pad old_lp = (*cfun->eh->lp_array)[old_index]; + eh_landing_pad new_lp = gen_eh_landing_pad (old_lp->region); + new_lp->post_landing_pad = old_lp->post_landing_pad; + new_lp->landing_pad = new_label; + index_map[old_index] = new_lp->index; + } + XEXP (note, 0) = GEN_INT (index_map[old_index]); + + /* Adjust the edge to the new destination. */ + redirect_edge_succ (e, new_bb); + } + else + ei_next (&ei); +} + +/* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions. + Add a new landing pad that will just jump to the old one and split the + edges so that no EH edge crosses partitions. */ + +static void +dw2_fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb) +{ + eh_landing_pad new_lp; + edge_iterator ei; + edge e; + + /* Generate the new landing-pad structure. */ + new_lp = gen_eh_landing_pad (old_lp->region); + new_lp->post_landing_pad = old_lp->post_landing_pad; + new_lp->landing_pad = gen_label_rtx (); + LABEL_PRESERVE_P (new_lp->landing_pad) = 1; + + /* Create the forwarder block. */ + basic_block new_bb = create_eh_forwarder_block (new_lp->landing_pad, old_bb); + + /* Fix up the edges. */ + for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; ) + if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb)) { rtx_insn *insn = BB_END (e->src); rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); @@ -1572,6 +1635,7 @@ sanitize_hot_paths (bool walk_up, unsigned int cold_bb_count, hot_bbs_to_check.safe_push (reach_bb); } } + hot_bbs_to_check.release (); return cold_bb_count; } @@ -1651,9 +1715,11 @@ find_rarely_executed_basic_blocks_and_crossing_edges (void) /* The format of .gcc_except_table does not allow landing pads to be in a different partition as the throw. Fix this by either - moving or duplicating the landing pads. */ + moving the landing pads or inserting forwarder landing pads. */ if (cfun->eh->lp_array) { + const bool sjlj + = (targetm_common.except_unwind_info (&global_options) == UI_SJLJ); unsigned i; eh_landing_pad lp; @@ -1685,13 +1751,18 @@ find_rarely_executed_basic_blocks_and_crossing_edges (void) which ^= BB_HOT_PARTITION | BB_COLD_PARTITION; BB_SET_PARTITION (bb, which); } + else if (sjlj) + sjlj_fix_up_crossing_landing_pad (bb); else - fix_up_crossing_landing_pad (lp, bb); + dw2_fix_up_crossing_landing_pad (lp, bb); + + /* There is a single, common landing pad in SJLJ mode. */ + if (sjlj) + break; } } /* Mark every edge that crosses between sections. */ - FOR_EACH_BB_FN (bb, cfun) FOR_EACH_EDGE (e, ei, bb->succs) { @@ -2861,8 +2932,8 @@ pass_partition_blocks::gate (function *fun) { /* The optimization to partition hot/cold basic blocks into separate sections of the .o file does not work well with linkonce or with - user defined section attributes. Don't call it if either case - arises. */ + user defined section attributes or with naked attribute. Don't call + it if either case arises. */ return (flag_reorder_blocks_and_partition && optimize /* See pass_reorder_blocks::gate. We should not partition if @@ -2870,6 +2941,7 @@ pass_partition_blocks::gate (function *fun) && optimize_function_for_speed_p (fun) && !DECL_COMDAT_GROUP (current_function_decl) && !lookup_attribute ("section", DECL_ATTRIBUTES (fun->decl)) + && !lookup_attribute ("naked", DECL_ATTRIBUTES (fun->decl)) /* Workaround a bug in GDB where read_partial_die doesn't cope with DIEs with DW_AT_ranges, see PR81115. */ && !(in_lto_p && MAIN_NAME_P (DECL_NAME (fun->decl)))); diff --git a/contrib/gcc-8.0/gcc/c-family/c-ada-spec.c b/contrib/gcc-8.0/gcc/c-family/c-ada-spec.c index bc137a6eae..30fdb59d55 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-ada-spec.c +++ b/contrib/gcc-8.0/gcc/c-family/c-ada-spec.c @@ -2734,19 +2734,25 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) if (TYPE_NAME (typ)) { - /* If types have same representation, and same name (ignoring - casing), then ignore the second type. */ + /* If the types have the same name (ignoring casing), then ignore + the second type, but forward declare the first if need be. */ if (type_name (typ) == type_name (TREE_TYPE (t)) || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t)))) { + if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub)) + { + INDENT (spc); + dump_forward_type (buffer, typ, t, 0); + } + TREE_VISITED (t) = 1; return 0; } INDENT (spc); - if (RECORD_OR_UNION_TYPE_P (typ)) - dump_forward_type (buffer, stub, t, spc); + if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub)) + dump_forward_type (buffer, typ, t, spc); pp_string (buffer, "subtype "); dump_ada_node (buffer, t, type, spc, false, true); diff --git a/contrib/gcc-8.0/gcc/c-family/c-attribs.c b/contrib/gcc-8.0/gcc/c-family/c-attribs.c index e0630885cc..c9e799e0fc 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-attribs.c +++ b/contrib/gcc-8.0/gcc/c-family/c-attribs.c @@ -403,7 +403,7 @@ const struct attribute_spec c_common_attribute_table[] = 0, 0, true, false, false, false, handle_no_address_safety_analysis_attribute, NULL }, - { "no_sanitize", 1, 1, true, false, false, false, + { "no_sanitize", 1, -1, true, false, false, false, handle_no_sanitize_attribute, NULL }, { "no_sanitize_address", 0, 0, true, false, false, false, handle_no_sanitize_address_attribute, NULL }, @@ -445,6 +445,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_omp_declare_target_attribute, NULL }, { "omp declare target link", 0, 0, true, false, false, false, handle_omp_declare_target_attribute, NULL }, + { "omp declare target implicit", 0, 0, true, false, false, false, + handle_omp_declare_target_attribute, NULL }, { "alloc_align", 1, 1, false, true, true, false, handle_alloc_align_attribute, attr_alloc_exclusions }, @@ -517,8 +519,13 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args), if (TYPE_P (*node)) { if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - *node = build_variant_type_copy (*node); - TYPE_PACKED (*node) = 1; + { + warning (OPT_Wattributes, + "%qE attribute ignored for type %qT", name, *node); + *no_add_attrs = true; + } + else + TYPE_PACKED (*node) = 1; } else if (TREE_CODE (*node) == FIELD_DECL) { @@ -683,22 +690,26 @@ static tree handle_no_sanitize_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs) { + unsigned int flags = 0; *no_add_attrs = true; - tree id = TREE_VALUE (args); if (TREE_CODE (*node) != FUNCTION_DECL) { warning (OPT_Wattributes, "%qE attribute ignored", name); return NULL_TREE; } - if (TREE_CODE (id) != STRING_CST) + for (; args; args = TREE_CHAIN (args)) { - error ("no_sanitize argument not a string"); - return NULL_TREE; - } + tree id = TREE_VALUE (args); + if (TREE_CODE (id) != STRING_CST) + { + error ("no_sanitize argument not a string"); + return NULL_TREE; + } - char *string = ASTRDUP (TREE_STRING_POINTER (id)); - unsigned int flags = parse_no_sanitize_attribute (string); + char *string = ASTRDUP (TREE_STRING_POINTER (id)); + flags |= parse_no_sanitize_attribute (string); + } add_no_sanitize_value (*node, flags); diff --git a/contrib/gcc-8.0/gcc/c-family/c-common.c b/contrib/gcc-8.0/gcc/c-family/c-common.c index 7e6905e791..dbbaa81956 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-common.c +++ b/contrib/gcc-8.0/gcc/c-family/c-common.c @@ -5403,10 +5403,8 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num) if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE) return; - /* When not optimizing diagnose the simple cases of null arguments. - When optimization is enabled defer the checking until expansion - when more cases can be detected. */ - if (integer_zerop (param)) + /* Diagnose the simple cases of null arguments. */ + if (integer_zerop (fold_for_warn (param))) { warning_at (pctx->loc, OPT_Wnonnull, "null argument where non-null " "required (argument %lu)", (unsigned long) param_num); @@ -6168,10 +6166,11 @@ c_common_to_target_charset (HOST_WIDE_INT c) /* Fold an offsetof-like expression. EXPR is a nested sequence of component references with an INDIRECT_REF of a constant at the bottom; much like the - traditional rendering of offsetof as a macro. Return the folded result. */ + traditional rendering of offsetof as a macro. TYPE is the desired type of + the whole expression. Return the folded result. */ tree -fold_offsetof_1 (tree expr, enum tree_code ctx) +fold_offsetof (tree expr, tree type, enum tree_code ctx) { tree base, off, t; tree_code code = TREE_CODE (expr); @@ -6196,10 +6195,10 @@ fold_offsetof_1 (tree expr, enum tree_code ctx) error ("cannot apply % to a non constant address"); return error_mark_node; } - return TREE_OPERAND (expr, 0); + return convert (type, TREE_OPERAND (expr, 0)); case COMPONENT_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); if (base == error_mark_node) return base; @@ -6216,7 +6215,7 @@ fold_offsetof_1 (tree expr, enum tree_code ctx) break; case ARRAY_REF: - base = fold_offsetof_1 (TREE_OPERAND (expr, 0), code); + base = fold_offsetof (TREE_OPERAND (expr, 0), type, code); if (base == error_mark_node) return base; @@ -6273,23 +6272,16 @@ fold_offsetof_1 (tree expr, enum tree_code ctx) /* Handle static members of volatile structs. */ t = TREE_OPERAND (expr, 1); gcc_checking_assert (VAR_P (get_base_address (t))); - return fold_offsetof_1 (t); + return fold_offsetof (t, type); default: gcc_unreachable (); } + if (!POINTER_TYPE_P (type)) + return size_binop (PLUS_EXPR, base, convert (type, off)); return fold_build_pointer_plus (base, off); } - -/* Likewise, but convert it to the return type of offsetof. */ - -tree -fold_offsetof (tree expr) -{ - return convert (size_type_node, fold_offsetof_1 (expr)); -} - /* *PTYPE is an incomplete array. Complete it with a domain based on INITIAL_VALUE. If INITIAL_VALUE is not present, use 1 if DO_DEFAULT diff --git a/contrib/gcc-8.0/gcc/c-family/c-common.h b/contrib/gcc-8.0/gcc/c-family/c-common.h index 6cf7614f68..f2c66628e5 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-common.h +++ b/contrib/gcc-8.0/gcc/c-family/c-common.h @@ -1033,8 +1033,8 @@ extern bool c_dump_tree (void *, tree); extern void verify_sequence_points (tree); -extern tree fold_offsetof_1 (tree, tree_code ctx = ERROR_MARK); -extern tree fold_offsetof (tree); +extern tree fold_offsetof (tree, tree = size_type_node, + tree_code ctx = ERROR_MARK); extern int complete_array_type (tree *, tree, bool); diff --git a/contrib/gcc-8.0/gcc/c-family/c-cppbuiltin.c b/contrib/gcc-8.0/gcc/c-family/c-cppbuiltin.c index 3fc4fa9cd6..18821eca88 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-cppbuiltin.c +++ b/contrib/gcc-8.0/gcc/c-family/c-cppbuiltin.c @@ -972,9 +972,13 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_aggregate_bases=201603"); cpp_define (pfile, "__cpp_deduction_guides=201611"); cpp_define (pfile, "__cpp_noexcept_function_type=201510"); + /* Old macro, superseded by + __cpp_nontype_template_parameter_auto. */ cpp_define (pfile, "__cpp_template_auto=201606"); cpp_define (pfile, "__cpp_structured_bindings=201606"); cpp_define (pfile, "__cpp_variadic_using=201611"); + cpp_define (pfile, "__cpp_guaranteed_copy_elision=201606"); + cpp_define (pfile, "__cpp_nontype_template_parameter_auto=201606"); } if (flag_concepts) cpp_define (pfile, "__cpp_concepts=201507"); diff --git a/contrib/gcc-8.0/gcc/c-family/c-omp.c b/contrib/gcc-8.0/gcc/c-family/c-omp.c index a076e3c083..8922759124 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-omp.c +++ b/contrib/gcc-8.0/gcc/c-family/c-omp.c @@ -373,8 +373,11 @@ c_finish_omp_atomic (location_t loc, enum tree_code code, } } if (blhs) - x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x, - bitsize_int (bitsize), bitsize_int (bitpos)); + { + x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x, + bitsize_int (bitsize), bitsize_int (bitpos)); + type = TREE_TYPE (blhs); + } x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR, loc, x, NULL_TREE); if (rhs1 && rhs1 != orig_lhs) @@ -1611,5 +1614,13 @@ c_omp_predetermined_sharing (tree decl) if (TREE_READONLY (decl)) return OMP_CLAUSE_DEFAULT_SHARED; + /* Predetermine artificial variables holding integral values, those + are usually result of gimplify_one_sizepos or SAVE_EXPR + gimplification. */ + if (VAR_P (decl) + && DECL_ARTIFICIAL (decl) + && INTEGRAL_TYPE_P (TREE_TYPE (decl))) + return OMP_CLAUSE_DEFAULT_SHARED; + return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } diff --git a/contrib/gcc-8.0/gcc/c-family/c-opts.c b/contrib/gcc-8.0/gcc/c-family/c-opts.c index 3db01d453a..9011902794 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-opts.c +++ b/contrib/gcc-8.0/gcc/c-family/c-opts.c @@ -417,8 +417,6 @@ c_common_handle_option (size_t scode, const char *arg, int value, value = 2; } warn_abi_version = value; - if (flag_abi_compat_version == -1) - flag_abi_compat_version = value; break; case OPT_fcanonical_system_headers: @@ -915,31 +913,48 @@ c_common_post_options (const char **pfilename) if (flag_declone_ctor_dtor == -1) flag_declone_ctor_dtor = optimize_size; - if (warn_abi_version == -1) - { - if (flag_abi_compat_version != -1) - warn_abi_version = flag_abi_compat_version; - else - warn_abi_version = 0; - } - if (flag_abi_compat_version == 1) { warning (0, "%<-fabi-compat-version=1%> is not supported, using =2"); flag_abi_compat_version = 2; } - else if (flag_abi_compat_version == -1) + + /* Change flag_abi_version to be the actual current ABI level, for the + benefit of c_cpp_builtins, and to make comparison simpler. */ + const int latest_abi_version = 13; + /* Generate compatibility aliases for ABI v11 (7.1) by default. */ + const int abi_compat_default = 11; + +#define clamp(X) if (X == 0 || X > latest_abi_version) X = latest_abi_version + clamp (flag_abi_version); + clamp (warn_abi_version); + clamp (flag_abi_compat_version); +#undef clamp + + /* Default -Wabi= or -fabi-compat-version= from each other. */ + if (warn_abi_version == -1 && flag_abi_compat_version != -1) + warn_abi_version = flag_abi_compat_version; + else if (flag_abi_compat_version == -1 && warn_abi_version != -1) + flag_abi_compat_version = warn_abi_version; + else if (warn_abi_version == -1 && flag_abi_compat_version == -1) { - /* Generate compatibility aliases for ABI v11 (7.1) by default. */ - flag_abi_compat_version - = (flag_abi_version == 0 ? 11 : 0); + warn_abi_version = latest_abi_version; + if (flag_abi_version == latest_abi_version) + { + if (warning (OPT_Wabi, "-Wabi won't warn about anything")) + { + inform (input_location, "-Wabi warns about differences " + "from the most up-to-date ABI, which is also used " + "by default"); + inform (input_location, "use e.g. -Wabi=11 to warn about " + "changes from GCC 7"); + } + flag_abi_compat_version = abi_compat_default; + } + else + flag_abi_compat_version = latest_abi_version; } - /* Change flag_abi_version to be the actual current ABI level for the - benefit of c_cpp_builtins. */ - if (flag_abi_version == 0) - flag_abi_version = 12; - /* By default, enable the new inheriting constructor semantics along with ABI 11. New and old should coexist fine, but it is a change in what artificial symbols are generated. */ diff --git a/contrib/gcc-8.0/gcc/c-family/c-ubsan.c b/contrib/gcc-8.0/gcc/c-family/c-ubsan.c index ae6e25043b..b8036805e3 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-ubsan.c +++ b/contrib/gcc-8.0/gcc/c-family/c-ubsan.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "asan.h" +#include "langhooks.h" /* Instrument division by zero and INT_MIN / -1. If not instrumenting, return NULL_TREE. */ @@ -44,8 +45,9 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) /* At this point both operands should have the same type, because they are already converted to RESULT_TYPE. Use TYPE_MAIN_VARIANT since typedefs can confuse us. */ - gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0)) - == TYPE_MAIN_VARIANT (TREE_TYPE (op1))); + tree top0 = TYPE_MAIN_VARIANT (type); + tree top1 = TYPE_MAIN_VARIANT (TREE_TYPE (op1)); + gcc_checking_assert (lang_hooks.types_compatible_p (top0, top1)); op0 = unshare_expr (op0); op1 = unshare_expr (op1); diff --git a/contrib/gcc-8.0/gcc/c-family/c-warn.c b/contrib/gcc-8.0/gcc/c-family/c-warn.c index d0d9c7894a..0991312835 100644 --- a/contrib/gcc-8.0/gcc/c-family/c-warn.c +++ b/contrib/gcc-8.0/gcc/c-family/c-warn.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "gcc-rich-location.h" #include "gimplify.h" #include "c-family/c-indentation.h" +#include "calls.h" /* Print a warning if a constant expression had overflow in folding. Invoke this function on every expression that the language @@ -798,6 +799,13 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee, tem = tree_strip_nop_conversions (src); if (TREE_CODE (tem) == ADDR_EXPR) tem = TREE_OPERAND (tem, 0); + + /* Avoid diagnosing sizeof SRC when SRC is declared with + attribute nonstring. */ + tree dummy; + if (get_attr_nonstring_decl (tem, &dummy)) + return; + if (operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF)) warning_at (sizeof_arg_loc[idx], OPT_Wsizeof_pointer_memaccess, "argument to % in %qD call is the same " @@ -1897,7 +1905,8 @@ warn_for_memset (location_t loc, tree arg0, tree arg2, { tree elt_type = TREE_TYPE (type); tree domain = TYPE_DOMAIN (type); - if (!integer_onep (TYPE_SIZE_UNIT (elt_type)) + if (COMPLETE_TYPE_P (elt_type) + && !integer_onep (TYPE_SIZE_UNIT (elt_type)) && domain != NULL_TREE && TYPE_MAX_VALUE (domain) && TYPE_MIN_VALUE (domain) @@ -2246,18 +2255,16 @@ diagnose_mismatched_attributes (tree olddecl, tree newdecl) newdecl); /* Diagnose inline __attribute__ ((noinline)) which is silly. */ - const char *noinline = "noinline"; - if (DECL_DECLARED_INLINE_P (newdecl) && DECL_UNINLINABLE (olddecl) - && lookup_attribute (noinline, DECL_ATTRIBUTES (olddecl))) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) warned |= warning (OPT_Wattributes, "inline declaration of %qD follows " - "declaration with attribute %qs", newdecl, noinline); + "declaration with attribute %qs", newdecl, "noinline"); else if (DECL_DECLARED_INLINE_P (olddecl) && DECL_UNINLINABLE (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute " - "%qs follows inline declaration", newdecl, noinline); + "%qs follows inline declaration", newdecl, "noinline"); return warned; } diff --git a/contrib/gcc-8.0/gcc/c-family/c.opt b/contrib/gcc-8.0/gcc/c-family/c.opt index a4c8c8ffcb..f591b39be5 100644 --- a/contrib/gcc-8.0/gcc/c-family/c.opt +++ b/contrib/gcc-8.0/gcc/c-family/c.opt @@ -1339,8 +1339,8 @@ Driver static-libmpxwrappers Driver -fcilkplus Undocumented -C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0) +fcilkplus +C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0) Undocumented Deprecated in GCC 8. This switch has no effect. fconcepts diff --git a/contrib/gcc-8.0/gcc/c/c-convert.c b/contrib/gcc-8.0/gcc/c/c-convert.c index b57bb8ea93..6165e145c0 100644 --- a/contrib/gcc-8.0/gcc/c/c-convert.c +++ b/contrib/gcc-8.0/gcc/c/c-convert.c @@ -115,6 +115,7 @@ convert (tree type, tree expr) && COMPLETE_TYPE_P (type)) { expr = save_expr (expr); + expr = c_fully_fold (expr, false, NULL); tree check = ubsan_instrument_float_cast (loc, type, expr); expr = fold_build1 (FIX_TRUNC_EXPR, type, expr); if (check == NULL_TREE) diff --git a/contrib/gcc-8.0/gcc/c/c-decl.c b/contrib/gcc-8.0/gcc/c/c-decl.c index f0198ec81c..4da9fe994f 100644 --- a/contrib/gcc-8.0/gcc/c/c-decl.c +++ b/contrib/gcc-8.0/gcc/c/c-decl.c @@ -1239,8 +1239,9 @@ pop_scope (void) && DECL_ABSTRACT_ORIGIN (p) != NULL_TREE && DECL_ABSTRACT_ORIGIN (p) != p) TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1; - if (!DECL_EXTERNAL (p) + if (!TREE_PUBLIC (p) && !DECL_INITIAL (p) + && !b->nested && scope != file_scope && scope != external_scope) { @@ -1256,7 +1257,7 @@ pop_scope (void) in the same translation unit." */ if (!flag_gnu89_inline && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p)) - && scope != external_scope) + && scope == external_scope) pedwarn (input_location, 0, "inline function %q+D declared but never defined", p); DECL_EXTERNAL (p) = 1; @@ -4632,8 +4633,8 @@ c_decl_attributes (tree *node, tree attributes, int flags) { if (VAR_P (*node) && !lang_hooks.types.omp_mappable_type (TREE_TYPE (*node))) - error ("%q+D in declare target directive does not have mappable type", - *node); + attributes = tree_cons (get_identifier ("omp declare target implicit"), + NULL_TREE, attributes); else attributes = tree_cons (get_identifier ("omp declare target"), NULL_TREE, attributes); @@ -5212,7 +5213,27 @@ finish_decl (tree decl, location_t init_loc, tree init, diagnose_uninitialized_cst_member (decl, type); } - invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); + if (flag_openmp + && VAR_P (decl) + && lookup_attribute ("omp declare target implicit", + DECL_ATTRIBUTES (decl))) + { + DECL_ATTRIBUTES (decl) + = remove_attribute ("omp declare target implicit", + DECL_ATTRIBUTES (decl)); + if (!lang_hooks.types.omp_mappable_type (TREE_TYPE (decl))) + error ("%q+D in declare target directive does not have mappable type", + decl); + else if (!lookup_attribute ("omp declare target", + DECL_ATTRIBUTES (decl)) + && !lookup_attribute ("omp declare target link", + DECL_ATTRIBUTES (decl))) + DECL_ATTRIBUTES (decl) + = tree_cons (get_identifier ("omp declare target"), + NULL_TREE, DECL_ATTRIBUTES (decl)); + } + + invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); } /* Given a parsed parameter declaration, decode it into a PARM_DECL. diff --git a/contrib/gcc-8.0/gcc/c/c-fold.c b/contrib/gcc-8.0/gcc/c/c-fold.c index 480e34ce4f..d276e635a2 100644 --- a/contrib/gcc-8.0/gcc/c/c-fold.c +++ b/contrib/gcc-8.0/gcc/c/c-fold.c @@ -473,7 +473,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, && (op1 = get_base_address (op0)) != NULL_TREE && INDIRECT_REF_P (op1) && TREE_CONSTANT (TREE_OPERAND (op1, 0))) - ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0)); + ret = fold_offsetof (op0, TREE_TYPE (expr)); else if (op0 != orig_op0 || in_init) ret = in_init ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) diff --git a/contrib/gcc-8.0/gcc/c/c-parser.c b/contrib/gcc-8.0/gcc/c/c-parser.c index 47720861d3..ece6b92024 100644 --- a/contrib/gcc-8.0/gcc/c/c-parser.c +++ b/contrib/gcc-8.0/gcc/c/c-parser.c @@ -2143,10 +2143,12 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, tree d = start_decl (declarator, specs, false, chainon (postfix_attrs, all_prefix_attrs)); - if (d && TREE_CODE (d) == FUNCTION_DECL) - if (declarator->kind == cdk_function) - if (DECL_ARGUMENTS (d) == NULL_TREE) - DECL_ARGUMENTS (d) = declarator->u.arg_info->parms; + if (d + && TREE_CODE (d) == FUNCTION_DECL + && declarator->kind == cdk_function + && DECL_ARGUMENTS (d) == NULL_TREE + && DECL_INITIAL (d) == NULL_TREE) + DECL_ARGUMENTS (d) = declarator->u.arg_info->parms; if (omp_declare_simd_clauses.exists ()) { tree parms = NULL_TREE; @@ -6261,61 +6263,104 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, } /* Parse an asm statement, a GNU extension. This is a full-blown asm - statement with inputs, outputs, clobbers, and volatile tag - allowed. + statement with inputs, outputs, clobbers, and volatile, inline, and goto + tags allowed. + + asm-qualifier: + volatile + inline + goto + + asm-qualifier-list: + asm-qualifier-list asm-qualifier + asm-qualifier asm-statement: - asm type-qualifier[opt] ( asm-argument ) ; - asm type-qualifier[opt] goto ( asm-goto-argument ) ; + asm asm-qualifier-list[opt] ( asm-argument ) ; asm-argument: asm-string-literal asm-string-literal : asm-operands[opt] asm-string-literal : asm-operands[opt] : asm-operands[opt] - asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt] - - asm-goto-argument: + asm-string-literal : asm-operands[opt] : asm-operands[opt] \ + : asm-clobbers[opt] asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \ : asm-goto-operands - Qualifiers other than volatile are accepted in the syntax but - warned for. */ + The form with asm-goto-operands is valid if and only if the + asm-qualifier-list contains goto, and is the only allowed form in that case. + Duplicate asm-qualifiers are not allowed. */ static tree c_parser_asm_statement (c_parser *parser) { - tree quals, str, outputs, inputs, clobbers, labels, ret; - bool simple, is_goto; + tree str, outputs, inputs, clobbers, labels, ret; + bool simple; location_t asm_loc = c_parser_peek_token (parser)->location; int section, nsections; gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); c_parser_consume_token (parser); - if (c_parser_next_token_is_keyword (parser, RID_VOLATILE)) - { - quals = c_parser_peek_token (parser)->value; - c_parser_consume_token (parser); - } - else if (c_parser_next_token_is_keyword (parser, RID_CONST) - || c_parser_next_token_is_keyword (parser, RID_RESTRICT)) - { - warning_at (c_parser_peek_token (parser)->location, - 0, - "%E qualifier ignored on asm", - c_parser_peek_token (parser)->value); - quals = NULL_TREE; - c_parser_consume_token (parser); - } - else - quals = NULL_TREE; - is_goto = false; - if (c_parser_next_token_is_keyword (parser, RID_GOTO)) + /* Handle the asm-qualifier-list. */ + location_t volatile_loc = UNKNOWN_LOCATION; + location_t inline_loc = UNKNOWN_LOCATION; + location_t goto_loc = UNKNOWN_LOCATION; + for (;;) { - c_parser_consume_token (parser); - is_goto = true; + c_token *token = c_parser_peek_token (parser); + location_t loc = token->location; + switch (token->keyword) + { + case RID_VOLATILE: + if (volatile_loc) + { + error_at (loc, "duplicate asm qualifier %qE", token->value); + inform (volatile_loc, "first seen here"); + } + else + volatile_loc = loc; + c_parser_consume_token (parser); + continue; + + case RID_INLINE: + if (inline_loc) + { + error_at (loc, "duplicate asm qualifier %qE", token->value); + inform (inline_loc, "first seen here"); + } + else + inline_loc = loc; + c_parser_consume_token (parser); + continue; + + case RID_GOTO: + if (goto_loc) + { + error_at (loc, "duplicate asm qualifier %qE", token->value); + inform (goto_loc, "first seen here"); + } + else + goto_loc = loc; + c_parser_consume_token (parser); + continue; + + case RID_CONST: + case RID_RESTRICT: + warning_at (loc, 0, "%qE is not an asm qualifier", token->value); + c_parser_consume_token (parser); + continue; + + default: + break; + } + break; } + bool is_volatile = (volatile_loc != UNKNOWN_LOCATION); + bool is_inline = (inline_loc != UNKNOWN_LOCATION); + bool is_goto = (goto_loc != UNKNOWN_LOCATION); + /* ??? Follow the C++ parser rather than using the lex_untranslated_string kludge. */ parser->lex_untranslated_string = true; @@ -6390,8 +6435,9 @@ c_parser_asm_statement (c_parser *parser) if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) c_parser_skip_to_end_of_block_or_statement (parser); - ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs, - clobbers, labels, simple)); + ret = build_asm_stmt (is_volatile, + build_asm_expr (asm_loc, str, outputs, inputs, + clobbers, labels, simple, is_inline)); error: parser->lex_untranslated_string = false; diff --git a/contrib/gcc-8.0/gcc/c/c-tree.h b/contrib/gcc-8.0/gcc/c/c-tree.h index ae1a1e60d4..aa66aa27b3 100644 --- a/contrib/gcc-8.0/gcc/c/c-tree.h +++ b/contrib/gcc-8.0/gcc/c/c-tree.h @@ -677,8 +677,9 @@ extern tree build_compound_literal (location_t, tree, tree, bool, extern void check_compound_literal_type (location_t, struct c_type_name *); extern tree c_start_case (location_t, location_t, tree, bool); extern void c_finish_case (tree, tree); -extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool); -extern tree build_asm_stmt (tree, tree); +extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool, + bool); +extern tree build_asm_stmt (bool, tree); extern int c_types_compatible_p (tree, tree); extern tree c_begin_compound_stmt (bool); extern tree c_end_compound_stmt (location_t, tree, bool); diff --git a/contrib/gcc-8.0/gcc/c/c-typeck.c b/contrib/gcc-8.0/gcc/c/c-typeck.c index ffd06447f1..7b90b5cd2f 100644 --- a/contrib/gcc-8.0/gcc/c/c-typeck.c +++ b/contrib/gcc-8.0/gcc/c/c-typeck.c @@ -3840,7 +3840,12 @@ pointer_diff (location_t loc, tree op0, tree op1, tree *instrument_expr) op0 = build_binary_op (loc, MINUS_EXPR, convert (inttype, op0), convert (inttype, op1), false); else - op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1); + { + /* Cast away qualifiers. */ + op0 = convert (c_common_type (TREE_TYPE (op0), TREE_TYPE (op0)), op0); + op1 = convert (c_common_type (TREE_TYPE (op1), TREE_TYPE (op1)), op1); + op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1); + } /* This generates an error if op1 is pointer to incomplete type. */ if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1)))) @@ -4676,7 +4681,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, if (val && INDIRECT_REF_P (val) && TREE_CONSTANT (TREE_OPERAND (val, 0))) { - ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg)); + ret = fold_offsetof (arg, argtype); goto return_build_unary_op; } @@ -9311,6 +9316,65 @@ output_init_element (location_t loc, tree value, tree origtype, output_pending_init_elements (0, braced_init_obstack); } +/* For two FIELD_DECLs in the same chain, return -1 if field1 + comes before field2, 1 if field1 comes after field2 and + 0 if field1 == field2. */ + +static int +init_field_decl_cmp (tree field1, tree field2) +{ + if (field1 == field2) + return 0; + + tree bitpos1 = bit_position (field1); + tree bitpos2 = bit_position (field2); + if (tree_int_cst_equal (bitpos1, bitpos2)) + { + /* If one of the fields has non-zero bitsize, then that + field must be the last one in a sequence of zero + sized fields, fields after it will have bigger + bit_position. */ + if (TREE_TYPE (field1) != error_mark_node + && COMPLETE_TYPE_P (TREE_TYPE (field1)) + && integer_nonzerop (TREE_TYPE (field1))) + return 1; + if (TREE_TYPE (field2) != error_mark_node + && COMPLETE_TYPE_P (TREE_TYPE (field2)) + && integer_nonzerop (TREE_TYPE (field2))) + return -1; + /* Otherwise, fallback to DECL_CHAIN walk to find out + which field comes earlier. Walk chains of both + fields, so that if field1 and field2 are close to each + other in either order, it is found soon even for large + sequences of zero sized fields. */ + tree f1 = field1, f2 = field2; + while (1) + { + f1 = DECL_CHAIN (f1); + f2 = DECL_CHAIN (f2); + if (f1 == NULL_TREE) + { + gcc_assert (f2); + return 1; + } + if (f2 == NULL_TREE) + return -1; + if (f1 == field2) + return -1; + if (f2 == field1) + return 1; + if (!tree_int_cst_equal (bit_position (f1), bitpos1)) + return 1; + if (!tree_int_cst_equal (bit_position (f2), bitpos1)) + return -1; + } + } + else if (tree_int_cst_lt (bitpos1, bitpos2)) + return -1; + else + return 1; +} + /* Output any pending elements which have become next. As we output elements, constructor_unfilled_{fields,index} advances, which may cause other elements to become next; @@ -9382,25 +9446,18 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) } else if (RECORD_OR_UNION_TYPE_P (constructor_type)) { - tree ctor_unfilled_bitpos, elt_bitpos; - /* If the current record is complete we are done. */ if (constructor_unfilled_fields == NULL_TREE) break; - ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields); - elt_bitpos = bit_position (elt->purpose); - /* We can't compare fields here because there might be empty - fields in between. */ - if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos)) - { - constructor_unfilled_fields = elt->purpose; - output_init_element (input_location, elt->value, elt->origtype, - true, TREE_TYPE (elt->purpose), - elt->purpose, false, false, - braced_init_obstack); - } - else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos)) + int cmp = init_field_decl_cmp (constructor_unfilled_fields, + elt->purpose); + if (cmp == 0) + output_init_element (input_location, elt->value, elt->origtype, + true, TREE_TYPE (elt->purpose), + elt->purpose, false, false, + braced_init_obstack); + else if (cmp < 0) { /* Advance to the next smaller node. */ if (elt->left) @@ -9426,8 +9483,8 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) elt = elt->parent; elt = elt->parent; if (elt - && (tree_int_cst_lt (ctor_unfilled_bitpos, - bit_position (elt->purpose)))) + && init_field_decl_cmp (constructor_unfilled_fields, + elt->purpose) < 0) { next = elt->purpose; break; @@ -9922,9 +9979,9 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, (guaranteed to be 'volatile' or null) and ARGS (represented using an ASM_EXPR node). */ tree -build_asm_stmt (tree cv_qualifier, tree args) +build_asm_stmt (bool is_volatile, tree args) { - if (!ASM_VOLATILE_P (args) && cv_qualifier) + if (is_volatile) ASM_VOLATILE_P (args) = 1; return add_stmt (args); } @@ -9933,10 +9990,12 @@ build_asm_stmt (tree cv_qualifier, tree args) some INPUTS, and some CLOBBERS. The latter three may be NULL. SIMPLE indicates whether there was anything at all after the string in the asm expression -- asm("blah") and asm("blah" : ) - are subtly different. We use a ASM_EXPR node to represent this. */ + are subtly different. We use a ASM_EXPR node to represent this. + LOC is the location of the asm, and IS_INLINE says whether this + is asm inline. */ tree build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, - tree clobbers, tree labels, bool simple) + tree clobbers, tree labels, bool simple, bool is_inline) { tree tail; tree args; @@ -10054,6 +10113,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, as volatile. */ ASM_INPUT_P (args) = simple; ASM_VOLATILE_P (args) = (noutputs == 0); + ASM_INLINE_P (args) = is_inline; return args; } diff --git a/contrib/gcc-8.0/gcc/calls.c b/contrib/gcc-8.0/gcc/calls.c index 9eb0467311..e619f687b4 100644 --- a/contrib/gcc-8.0/gcc/calls.c +++ b/contrib/gcc-8.0/gcc/calls.c @@ -50,11 +50,13 @@ along with GCC; see the file COPYING3. If not see #include "tree-chkp.h" #include "tree-vrp.h" #include "tree-ssanames.h" +#include "tree-ssa-strlen.h" #include "rtl-chkp.h" #include "intl.h" #include "stringpool.h" #include "attribs.h" #include "builtins.h" +#include "gimple-fold.h" /* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */ #define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) @@ -1230,65 +1232,81 @@ static GTY(()) tree alloc_object_size_limit; static tree alloc_max_size (void) { - if (!alloc_object_size_limit) - { - alloc_object_size_limit = max_object_size (); + if (alloc_object_size_limit) + return alloc_object_size_limit; - if (warn_alloc_size_limit) - { - char *end = NULL; - errno = 0; - unsigned HOST_WIDE_INT unit = 1; - unsigned HOST_WIDE_INT limit - = strtoull (warn_alloc_size_limit, &end, 10); + alloc_object_size_limit = max_object_size (); - if (!errno) - { - if (end && *end) - { - /* Numeric option arguments are at most INT_MAX. Make it - possible to specify a larger value by accepting common - suffixes. */ - if (!strcmp (end, "kB")) - unit = 1000; - else if (!strcasecmp (end, "KiB") || strcmp (end, "KB")) - unit = 1024; - else if (!strcmp (end, "MB")) - unit = HOST_WIDE_INT_UC (1000) * 1000; - else if (!strcasecmp (end, "MiB")) - unit = HOST_WIDE_INT_UC (1024) * 1024; - else if (!strcasecmp (end, "GB")) - unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000; - else if (!strcasecmp (end, "GiB")) - unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024; - else if (!strcasecmp (end, "TB")) - unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000; - else if (!strcasecmp (end, "TiB")) - unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024; - else if (!strcasecmp (end, "PB")) - unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000; - else if (!strcasecmp (end, "PiB")) - unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024; - else if (!strcasecmp (end, "EB")) - unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000 - * 1000; - else if (!strcasecmp (end, "EiB")) - unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024 - * 1024; - else - unit = 0; - } + if (!warn_alloc_size_limit) + return alloc_object_size_limit; - if (unit) - { - widest_int w = wi::mul (limit, unit); - if (w < wi::to_widest (alloc_object_size_limit)) - alloc_object_size_limit - = wide_int_to_tree (ptrdiff_type_node, w); - } - } + const char *optname = "-Walloc-size-larger-than="; + + char *end = NULL; + errno = 0; + unsigned HOST_WIDE_INT unit = 1; + unsigned HOST_WIDE_INT limit + = strtoull (warn_alloc_size_limit, &end, 10); + + /* If the value is too large to be represented use the maximum + representable value that strtoull sets limit to (setting + errno to ERANGE). */ + + if (end && *end) + { + /* Numeric option arguments are at most INT_MAX. Make it + possible to specify a larger value by accepting common + suffixes. */ + if (!strcmp (end, "kB")) + unit = 1000; + else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB")) + unit = 1024; + else if (!strcmp (end, "MB")) + unit = HOST_WIDE_INT_UC (1000) * 1000; + else if (!strcasecmp (end, "MiB")) + unit = HOST_WIDE_INT_UC (1024) * 1024; + else if (!strcasecmp (end, "GB")) + unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000; + else if (!strcasecmp (end, "GiB")) + unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024; + else if (!strcasecmp (end, "TB")) + unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000; + else if (!strcasecmp (end, "TiB")) + unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024; + else if (!strcasecmp (end, "PB")) + unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000; + else if (!strcasecmp (end, "PiB")) + unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024; + else if (!strcasecmp (end, "EB")) + unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000 + * 1000; + else if (!strcasecmp (end, "EiB")) + unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024 + * 1024; + else + { + /* This could mean an unknown suffix or a bad prefix, like + "+-1". */ + warning_at (UNKNOWN_LOCATION, 0, + "invalid argument %qs to %qs", + warn_alloc_size_limit, optname); + + /* Ignore the limit extracted by strtoull. */ + unit = 0; } } + + if (unit) + { + widest_int w = wi::mul (limit, unit); + if (w < wi::to_widest (alloc_object_size_limit)) + alloc_object_size_limit + = wide_int_to_tree (ptrdiff_type_node, w); + else + alloc_object_size_limit = build_all_ones_cst (size_type_node); + } + + return alloc_object_size_limit; } @@ -1586,8 +1604,12 @@ get_attr_nonstring_decl (tree expr, tree *ref) if (ref) *ref = decl; - if (TREE_CODE (decl) == COMPONENT_REF) + if (TREE_CODE (decl) == ARRAY_REF) + decl = TREE_OPERAND (decl, 0); + else if (TREE_CODE (decl) == COMPONENT_REF) decl = TREE_OPERAND (decl, 1); + else if (TREE_CODE (decl) == MEM_REF) + return get_attr_nonstring_decl (TREE_OPERAND (decl, 0), ref); if (DECL_P (decl) && lookup_attribute ("nonstring", DECL_ATTRIBUTES (decl))) @@ -1605,6 +1627,9 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) if (!fndecl || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) return; + if (!warn_stringop_overflow) + return; + bool with_bounds = CALL_WITH_BOUNDS_P (exp); unsigned nargs = call_expr_nargs (exp); @@ -1612,15 +1637,42 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) /* The bound argument to a bounded string function like strncpy. */ tree bound = NULL_TREE; + /* The range of lengths of a string argument to one of the comparison + functions. If the length is less than the bound it is used instead. */ + tree lenrng[2] = { NULL_TREE, NULL_TREE }; + /* It's safe to call "bounded" string functions with a non-string argument since the functions provide an explicit bound for this - purpose. */ - switch (DECL_FUNCTION_CODE (fndecl)) + purpose. The exception is strncat where the bound may refer to + either the destination or the source. */ + int fncode = DECL_FUNCTION_CODE (fndecl); + switch (fncode) { - case BUILT_IN_STPNCPY: - case BUILT_IN_STPNCPY_CHK: + case BUILT_IN_STRCMP: case BUILT_IN_STRNCMP: case BUILT_IN_STRNCASECMP: + { + /* For these, if one argument refers to one or more of a set + of string constants or arrays of known size, determine + the range of their known or possible lengths and use it + conservatively as the bound for the unbounded function, + and to adjust the range of the bound of the bounded ones. */ + unsigned stride = with_bounds ? 2 : 1; + for (unsigned argno = 0; + argno < MIN (nargs, 2 * stride) + && !(lenrng[1] && TREE_CODE (lenrng[1]) == INTEGER_CST); + argno += stride) + { + tree arg = CALL_EXPR_ARG (exp, argno); + if (!get_attr_nonstring_decl (arg)) + get_range_strlen (arg, lenrng); + } + } + /* Fall through. */ + + case BUILT_IN_STRNCAT: + case BUILT_IN_STPNCPY: + case BUILT_IN_STPNCPY_CHK: case BUILT_IN_STRNCPY: case BUILT_IN_STRNCPY_CHK: { @@ -1647,6 +1699,31 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) if (bound) get_size_range (bound, bndrng); + if (lenrng[1] && TREE_CODE (lenrng[1]) == INTEGER_CST) + { + /* Add one for the nul. */ + lenrng[1] = const_binop (PLUS_EXPR, TREE_TYPE (lenrng[1]), + lenrng[1], size_one_node); + + if (!bndrng[0]) + { + /* Conservatively use the upper bound of the lengths for + both the lower and the upper bound of the operation. */ + bndrng[0] = lenrng[1]; + bndrng[1] = lenrng[1]; + bound = void_type_node; + } + else + { + /* Replace the bound on the oparation with the upper bound + of the length of the string if the latter is smaller. */ + if (tree_int_cst_lt (lenrng[1], bndrng[0])) + bndrng[0] = lenrng[1]; + else if (tree_int_cst_lt (lenrng[1], bndrng[1])) + bndrng[1] = lenrng[1]; + } + } + /* Iterate over the built-in function's formal arguments and check each const char* against the actual argument. If the actual argument is declared attribute non-string issue a warning unless @@ -1687,30 +1764,98 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) if (!decl) continue; - tree type = TREE_TYPE (decl); - + /* The maximum number of array elements accessed. */ offset_int wibnd = 0; - if (bndrng[0]) + + if (argno && fncode == BUILT_IN_STRNCAT) + { + /* See if the bound in strncat is derived from the length + of the strlen of the destination (as it's expected to be). + If so, reset BOUND and FNCODE to trigger a warning. */ + tree dstarg = CALL_EXPR_ARG (exp, 0); + if (is_strlen_related_p (dstarg, bound)) + { + /* The bound applies to the destination, not to the source, + so reset these to trigger a warning without mentioning + the bound. */ + bound = NULL; + fncode = 0; + } + else if (bndrng[1]) + /* Use the upper bound of the range for strncat. */ + wibnd = wi::to_offset (bndrng[1]); + } + else if (bndrng[0]) + /* Use the lower bound of the range for functions other than + strncat. */ wibnd = wi::to_offset (bndrng[0]); + /* Determine the size of the argument array if it is one. */ offset_int asize = wibnd; + bool known_size = false; + tree type = TREE_TYPE (decl); + /* Determine the array size. For arrays of unknown bound and + pointers reset BOUND to trigger the appropriate warning. */ if (TREE_CODE (type) == ARRAY_TYPE) - if (tree arrbnd = TYPE_DOMAIN (type)) - { - if ((arrbnd = TYPE_MAX_VALUE (arrbnd))) - asize = wi::to_offset (arrbnd) + 1; - } + { + if (tree arrbnd = TYPE_DOMAIN (type)) + { + if ((arrbnd = TYPE_MAX_VALUE (arrbnd))) + { + asize = wi::to_offset (arrbnd) + 1; + known_size = true; + } + } + else if (bound == void_type_node) + bound = NULL_TREE; + } + else if (bound == void_type_node) + bound = NULL_TREE; location_t loc = EXPR_LOCATION (exp); + /* In a call to strncat with a bound in a range whose lower but + not upper bound is less than the array size, reset ASIZE to + be the same as the bound and the other variable to trigger + the apprpriate warning below. */ + if (fncode == BUILT_IN_STRNCAT + && bndrng[0] != bndrng[1] + && wi::ltu_p (wi::to_offset (bndrng[0]), asize) + && (!known_size + || wi::ltu_p (asize, wibnd))) + { + asize = wibnd; + bound = NULL_TREE; + fncode = 0; + } + bool warned = false; if (wi::ltu_p (asize, wibnd)) - warned = warning_at (loc, OPT_Wstringop_overflow_, - "%qD argument %i declared attribute % " - "is smaller than the specified bound %E", - fndecl, argno + 1, bndrng[0]); + { + if (bndrng[0] == bndrng[1]) + warned = warning_at (loc, OPT_Wstringop_overflow_, + "%qD argument %i declared attribute " + "% is smaller than the specified " + "bound %wu", + fndecl, argno + 1, wibnd.to_uhwi ()); + else if (wi::ltu_p (asize, wi::to_offset (bndrng[0]))) + warned = warning_at (loc, OPT_Wstringop_overflow_, + "%qD argument %i declared attribute " + "% is smaller than " + "the specified bound [%E, %E]", + fndecl, argno + 1, bndrng[0], bndrng[1]); + else + warned = warning_at (loc, OPT_Wstringop_overflow_, + "%qD argument %i declared attribute " + "% may be smaller than " + "the specified bound [%E, %E]", + fndecl, argno + 1, bndrng[0], bndrng[1]); + } + else if (fncode == BUILT_IN_STRNCAT) + ; /* Avoid warning for calls to strncat() when the bound + is equal to the size of the non-string argument. */ else if (!bound) warned = warning_at (loc, OPT_Wstringop_overflow_, "%qD argument %i declared attribute %", diff --git a/contrib/gcc-8.0/gcc/cfgcleanup.c b/contrib/gcc-8.0/gcc/cfgcleanup.c index 4a5dc29d14..4a3bfe16d0 100644 --- a/contrib/gcc-8.0/gcc/cfgcleanup.c +++ b/contrib/gcc-8.0/gcc/cfgcleanup.c @@ -1592,10 +1592,13 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2) if (crtl->shrink_wrapped && single_succ_p (bb1) && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun) - && !JUMP_P (BB_END (bb1)) + && (!JUMP_P (BB_END (bb1)) + /* Punt if the only successor is a fake edge to exit, the jump + must be some weird one. */ + || (single_succ_edge (bb1)->flags & EDGE_FAKE) != 0) && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1)))) return false; - + /* If BB1 has only one successor, we may be looking at either an unconditional jump, or a fake edge to exit. */ if (single_succ_p (bb1) diff --git a/contrib/gcc-8.0/gcc/cfgexpand.c b/contrib/gcc-8.0/gcc/cfgexpand.c index deab929600..018cf25712 100644 --- a/contrib/gcc-8.0/gcc/cfgexpand.c +++ b/contrib/gcc-8.0/gcc/cfgexpand.c @@ -1157,6 +1157,20 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) if (repr_decl == NULL_TREE) repr_decl = stack_vars[i].decl; data->asan_decl_vec.safe_push (repr_decl); + + /* Make sure a representative is unpoison if another + variable in the partition is handled by + use-after-scope sanitization. */ + if (asan_handled_variables != NULL + && !asan_handled_variables->contains (repr_decl)) + { + for (j = i; j != EOC; j = stack_vars[j].next) + if (asan_handled_variables->contains (stack_vars[j].decl)) + break; + if (j != EOC) + asan_handled_variables->add (repr_decl); + } + data->asan_alignb = MAX (data->asan_alignb, alignb); if (data->asan_base == NULL) data->asan_base = gen_reg_rtx (Pmode); @@ -1259,10 +1273,10 @@ set_parm_rtl (tree parm, rtx x) allocate it, which means that in-frame portion is just a pointer. ??? We've got a pseudo for sure here, do we actually dynamically allocate its spilling area if needed? - ??? Isn't it a problem when POINTER_SIZE also exceeds - MAX_SUPPORTED_STACK_ALIGNMENT, as on cris and lm32? */ + ??? Isn't it a problem when Pmode alignment also exceeds + MAX_SUPPORTED_STACK_ALIGNMENT, as can happen on cris and lm32? */ if (align > MAX_SUPPORTED_STACK_ALIGNMENT) - align = POINTER_SIZE; + align = GET_MODE_ALIGNMENT (Pmode); record_alignment_for_reg_var (align); } @@ -1383,7 +1397,7 @@ expand_one_ssa_partition (tree var) /* If the variable alignment is very large we'll dynamicaly allocate it, which means that in-frame portion is just a pointer. */ if (align > MAX_SUPPORTED_STACK_ALIGNMENT) - align = POINTER_SIZE; + align = GET_MODE_ALIGNMENT (Pmode); record_alignment_for_reg_var (align); @@ -1610,7 +1624,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand) /* If the variable alignment is very large we'll dynamicaly allocate it, which means that in-frame portion is just a pointer. */ if (align > MAX_SUPPORTED_STACK_ALIGNMENT) - align = POINTER_SIZE; + align = GET_MODE_ALIGNMENT (Pmode); } record_alignment_for_reg_var (align); @@ -3044,14 +3058,14 @@ expand_asm_stmt (gasm *stmt) generating_concat_p = 0; - if ((TREE_CODE (val) == INDIRECT_REF - && allows_mem) + if ((TREE_CODE (val) == INDIRECT_REF && allows_mem) || (DECL_P (val) && (allows_mem || REG_P (DECL_RTL (val))) && ! (REG_P (DECL_RTL (val)) && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type))) || ! allows_reg - || is_inout) + || is_inout + || TREE_ADDRESSABLE (type)) { op = expand_expr (val, NULL_RTX, VOIDmode, !allows_reg ? EXPAND_MEMORY : EXPAND_WRITE); @@ -3060,7 +3074,7 @@ expand_asm_stmt (gasm *stmt) if (! allows_reg && !MEM_P (op)) error ("output number %d not directly addressable", i); - if ((! allows_mem && MEM_P (op)) + if ((! allows_mem && MEM_P (op) && GET_MODE (op) != BLKmode) || GET_CODE (op) == CONCAT) { rtx old_op = op; @@ -6534,6 +6548,14 @@ pass_expand::execute (function *fun) find_many_sub_basic_blocks (blocks); purge_all_dead_edges (); + /* After initial rtl generation, call back to finish generating + exception support code. We need to do this before cleaning up + the CFG as the code does not expect dead landing pads. */ + if (fun->eh->region_tree != NULL) + finish_eh_generation (); + + /* Call expand_stack_alignment after finishing all + updates to crtl->preferred_stack_boundary. */ expand_stack_alignment (); /* Fixup REG_EQUIV notes in the prologue if there are tailcalls in this @@ -6541,12 +6563,6 @@ pass_expand::execute (function *fun) if (crtl->tail_call_emit) fixup_tail_calls (); - /* After initial rtl generation, call back to finish generating - exception support code. We need to do this before cleaning up - the CFG as the code does not expect dead landing pads. */ - if (fun->eh->region_tree != NULL) - finish_eh_generation (); - /* BB subdivision may have created basic blocks that are are only reachable from unlikely bbs but not marked as such in the profile. */ if (optimize) diff --git a/contrib/gcc-8.0/gcc/cfgrtl.c b/contrib/gcc-8.0/gcc/cfgrtl.c index de704ce16d..f6e4fecd64 100644 --- a/contrib/gcc-8.0/gcc/cfgrtl.c +++ b/contrib/gcc-8.0/gcc/cfgrtl.c @@ -984,6 +984,31 @@ block_label (basic_block block) return as_a (BB_HEAD (block)); } +/* Remove all barriers from BB_FOOTER of a BB. */ + +static void +remove_barriers_from_footer (basic_block bb) +{ + rtx_insn *insn = BB_FOOTER (bb); + + /* Remove barriers but keep jumptables. */ + while (insn) + { + if (BARRIER_P (insn)) + { + if (PREV_INSN (insn)) + SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn); + else + BB_FOOTER (bb) = NEXT_INSN (insn); + if (NEXT_INSN (insn)) + SET_PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn); + } + if (LABEL_P (insn)) + return; + insn = NEXT_INSN (insn); + } +} + /* Attempt to perform edge redirection by replacing possibly complex jump instruction by unconditional jump or removing jump completely. This can apply only if all edges now point to the same block. The parameters and @@ -1047,26 +1072,8 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout) /* Selectively unlink whole insn chain. */ if (in_cfglayout) { - rtx_insn *insn = BB_FOOTER (src); - delete_insn_chain (kill_from, BB_END (src), false); - - /* Remove barriers but keep jumptables. */ - while (insn) - { - if (BARRIER_P (insn)) - { - if (PREV_INSN (insn)) - SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn); - else - BB_FOOTER (src) = NEXT_INSN (insn); - if (NEXT_INSN (insn)) - SET_PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn); - } - if (LABEL_P (insn)) - break; - insn = NEXT_INSN (insn); - } + remove_barriers_from_footer (src); } else delete_insn_chain (kill_from, PREV_INSN (BB_HEAD (target)), @@ -1264,11 +1271,13 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb) /* If the substitution doesn't succeed, die. This can happen if the back end emitted unrecognizable instructions or if - target is exit block on some arches. */ + target is exit block on some arches. Or for crossing + jumps. */ if (!redirect_jump (as_a (insn), block_label (new_bb), 0)) { - gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)); + gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun) + || CROSSING_JUMP_P (insn)); return false; } } @@ -3315,8 +3324,15 @@ fixup_abnormal_edges (void) If it's placed after a trapping call (i.e. that call is the last insn anyway), we have no fallthru edge. Simply delete this use and don't try to insert - on the non-existent edge. */ - if (GET_CODE (PATTERN (insn)) != USE) + on the non-existent edge. + Similarly, sometimes a call that can throw is + followed in the source with __builtin_unreachable (), + meaning that there is UB if the call returns rather + than throws. If there weren't any instructions + following such calls before, supposedly even the ones + we've deleted aren't significant and can be + removed. */ + if (e) { /* We're not deleting it, we're moving it. */ insn->set_undeleted (); @@ -4370,6 +4386,7 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest) "Removing crossing jump while redirecting edge form %i to %i\n", e->src->index, dest->index); delete_insn (BB_END (src)); + remove_barriers_from_footer (src); e->flags |= EDGE_FALLTHRU; } @@ -4436,6 +4453,9 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest) else ret = redirect_branch_edge (e, dest); + if (!ret) + return NULL; + fixup_partition_crossing (ret); /* We don't want simplejumps in the insn stream during cfglayout. */ gcc_assert (!simplejump_p (BB_END (src)) || CROSSING_JUMP_P (BB_END (src))); diff --git a/contrib/gcc-8.0/gcc/cgraph.c b/contrib/gcc-8.0/gcc/cgraph.c index 9a7d54d7ce..9f3a2929f6 100644 --- a/contrib/gcc-8.0/gcc/cgraph.c +++ b/contrib/gcc-8.0/gcc/cgraph.c @@ -517,6 +517,9 @@ cgraph_node::create (tree decl) g->have_offload = true; } + if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + node->ifunc_resolver = true; + node->register_symbol (); if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) @@ -575,6 +578,8 @@ cgraph_node::create_alias (tree alias, tree target) alias_node->alias = true; if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL) alias_node->transparent_alias = alias_node->weakref = true; + if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias))) + alias_node->ifunc_resolver = true; return alias_node; } @@ -2299,7 +2304,7 @@ cgraph_node::get_availability (symtab_node *ref) avail = AVAIL_AVAILABLE; else if (transparent_alias) ultimate_alias_target (&avail, ref); - else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)) + else if (ifunc_resolver || lookup_attribute ("noipa", DECL_ATTRIBUTES (decl))) avail = AVAIL_INTERPOSABLE; else if (!externally_visible) diff --git a/contrib/gcc-8.0/gcc/cgraph.h b/contrib/gcc-8.0/gcc/cgraph.h index ee7ebb41c2..afb2745a84 100644 --- a/contrib/gcc-8.0/gcc/cgraph.h +++ b/contrib/gcc-8.0/gcc/cgraph.h @@ -530,6 +530,9 @@ public: /* Set when symbol can be streamed into bytecode for offloading. */ unsigned offloadable : 1; + /* Set when symbol is an IFUNC resolver. */ + unsigned ifunc_resolver : 1; + /* Ordering of all symtab entries. */ int order; @@ -2886,6 +2889,7 @@ cgraph_node::only_called_directly_or_aliased_p (void) { gcc_assert (!global.inlined_to); return (!force_output && !address_taken + && !ifunc_resolver && !used_from_other_partition && !DECL_VIRTUAL_P (decl) && !DECL_STATIC_CONSTRUCTOR (decl) diff --git a/contrib/gcc-8.0/gcc/cgraphunit.c b/contrib/gcc-8.0/gcc/cgraphunit.c index e418ec0414..212ee7b834 100644 --- a/contrib/gcc-8.0/gcc/cgraphunit.c +++ b/contrib/gcc-8.0/gcc/cgraphunit.c @@ -1307,7 +1307,7 @@ maybe_diag_incompatible_alias (tree alias, tree target) tree altype = TREE_TYPE (alias); tree targtype = TREE_TYPE (target); - bool ifunc = lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)); + bool ifunc = cgraph_node::get (alias)->ifunc_resolver; tree funcptr = altype; if (ifunc) diff --git a/contrib/gcc-8.0/gcc/collect2.c b/contrib/gcc-8.0/gcc/collect2.c index f26bc599f3..a96af137a4 100644 --- a/contrib/gcc-8.0/gcc/collect2.c +++ b/contrib/gcc-8.0/gcc/collect2.c @@ -201,6 +201,7 @@ static enum lto_mode_d lto_mode = LTO_MODE_NONE; bool helpflag; /* true if --help */ static int shared_obj; /* true if -shared */ +static int static_obj; /* true if -static */ static const char *c_file; /* .c for constructor/destructor list. */ static const char *o_file; /* .o for constructor/destructor list. */ @@ -255,6 +256,7 @@ bool may_unlink_output_file = false; #ifdef COLLECT_EXPORT_LIST /* Lists to keep libraries to be scanned for global constructors/destructors. */ static struct head libs; /* list of libraries */ +static struct head static_libs; /* list of statically linked libraries */ static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */ static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs, @@ -320,9 +322,7 @@ static void write_c_file_glob (FILE *, const char *); static void scan_libraries (const char *); #endif #ifdef COLLECT_EXPORT_LIST -#if 0 static int is_in_list (const char *, struct id *); -#endif static void write_aix_file (FILE *, struct id *); static char *resolve_lib_name (const char *); #endif @@ -911,6 +911,9 @@ main (int argc, char **argv) int first_file; int num_c_args; char **old_argv; +#ifdef COLLECT_EXPORT_LIST + bool is_static = false; +#endif int i; for (i = 0; i < USE_LD_MAX; i++) @@ -1241,6 +1244,8 @@ main (int argc, char **argv) *c_ptr++ = xstrdup (q); if (strcmp (q, "-shared") == 0) shared_obj = 1; + if (strcmp (q, "-static") == 0) + static_obj = 1; if (*q == '-' && q[1] == 'B') { *c_ptr++ = xstrdup (q); @@ -1269,6 +1274,9 @@ main (int argc, char **argv) /* Parse arguments. Remember output file spec, pass the rest to ld. */ /* After the first file, put in the c++ rt0. */ +#ifdef COLLECT_EXPORT_LIST + is_static = static_obj; +#endif first_file = 1; while ((arg = *++argv) != (char *) 0) { @@ -1374,6 +1382,18 @@ main (int argc, char **argv) #endif break; +#ifdef COLLECT_EXPORT_LIST + case 'b': + if (!strcmp (arg, "-bstatic")) + { + is_static = true; + } + else if (!strcmp (arg, "-bdynamic") || !strcmp (arg, "-bshared")) + { + is_static = false; + } + break; +#endif case 'l': if (first_file) { @@ -1390,6 +1410,8 @@ main (int argc, char **argv) /* Saving a full library name. */ add_to_list (&libs, s); + if (is_static) + add_to_list (&static_libs, s); } #endif break; @@ -1490,6 +1512,8 @@ main (int argc, char **argv) { /* Saving a full library name. */ add_to_list (&libs, arg); + if (is_static) + add_to_list (&static_libs, arg); } #endif } @@ -1501,6 +1525,8 @@ main (int argc, char **argv) { fprintf (stderr, "List of libraries:\n"); dump_list (stderr, "\t", libs.first); + fprintf (stderr, "List of statically linked libraries:\n"); + dump_list (stderr, "\t", static_libs.first); } /* The AIX linker will discard static constructors in object files if @@ -1525,9 +1551,11 @@ main (int argc, char **argv) this_filter &= ~SCAN_DWEH; #endif + /* Scan object files. */ while (export_object_lst < object) scan_prog_file (*export_object_lst++, PASS_OBJ, this_filter); + /* Scan libraries. */ for (; list; list = list->next) scan_prog_file (list->name, PASS_FIRST, this_filter); @@ -1975,7 +2003,6 @@ write_list (FILE *stream, const char *prefix, struct id *list) #ifdef COLLECT_EXPORT_LIST /* This function is really used only on AIX, but may be useful. */ -#if 0 static int is_in_list (const char *prefix, struct id *list) { @@ -1986,7 +2013,6 @@ is_in_list (const char *prefix, struct id *list) } return 0; } -#endif #endif /* COLLECT_EXPORT_LIST */ /* Added for debugging purpose. */ @@ -2818,7 +2844,12 @@ scan_prog_file (const char *prog_name, scanpass which_pass, case SYM_AIXI: if (! (filter & SCAN_CTOR)) break; - if (is_shared && !aixlazy_flag) + if (is_shared && !aixlazy_flag +#ifdef COLLECT_EXPORT_LIST + && ! static_obj + && ! is_in_list (prog_name, static_libs.first) +#endif + ) add_to_list (&constructors, name); break; diff --git a/contrib/gcc-8.0/gcc/combine.c b/contrib/gcc-8.0/gcc/combine.c index 3ad050fecf..899b6f1649 100644 --- a/contrib/gcc-8.0/gcc/combine.c +++ b/contrib/gcc-8.0/gcc/combine.c @@ -981,14 +981,17 @@ combine_validate_cost (rtx_insn *i0, rtx_insn *i1, rtx_insn *i2, rtx_insn *i3, } -/* Delete any insns that copy a register to itself. */ +/* Delete any insns that copy a register to itself. + Return true if the CFG was changed. */ -static void +static bool delete_noop_moves (void) { rtx_insn *insn, *next; basic_block bb; + bool edges_deleted = false; + FOR_EACH_BB_FN (bb, cfun) { for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); insn = next) @@ -999,10 +1002,12 @@ delete_noop_moves (void) if (dump_file) fprintf (dump_file, "deleting noop move %d\n", INSN_UID (insn)); - delete_insn_and_edges (insn); + edges_deleted |= delete_insn_and_edges (insn); } } } + + return edges_deleted; } @@ -1141,8 +1146,8 @@ insn_a_feeds_b (rtx_insn *a, rtx_insn *b) /* Main entry point for combiner. F is the first insn of the function. NREGS is the first unused pseudo-reg number. - Return nonzero if the combiner has turned an indirect jump - instruction into a direct jump. */ + Return nonzero if the CFG was changed (e.g. if the combiner has + turned an indirect jump instruction into a direct jump). */ static int combine_instructions (rtx_insn *f, unsigned int nregs) { @@ -1527,7 +1532,7 @@ retry: default_rtl_profile (); clear_bb_flags (); new_direct_jump_p |= purge_all_dead_edges (); - delete_noop_moves (); + new_direct_jump_p |= delete_noop_moves (); /* Clean up. */ obstack_free (&insn_link_obstack, NULL); @@ -4007,7 +4012,10 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, other insns to combine, but the destination of that SET is still live. Also do this if we started with two insns and (at least) one of the - resulting sets is a noop; this noop will be deleted later. */ + resulting sets is a noop; this noop will be deleted later. + + Also do this if we started with two insns neither of which was a simple + move. */ else if (insn_code_number < 0 && asm_noperands (newpat) < 0 && GET_CODE (newpat) == PARALLEL @@ -4035,13 +4043,15 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, one which uses any regs/memory set in between i2 and i3 can't be first. The PARALLEL might also have been pre-existing in i3, so we need to make sure that we won't wrongly hoist a SET to i2 - that would conflict with a death note present in there. */ + that would conflict with a death note present in there, or would + have its dest modified between i2 and i3. */ if (!modified_between_p (SET_SRC (set1), i2, i3) && !(REG_P (SET_DEST (set1)) && find_reg_note (i2, REG_DEAD, SET_DEST (set1))) && !(GET_CODE (SET_DEST (set1)) == SUBREG && find_reg_note (i2, REG_DEAD, SUBREG_REG (SET_DEST (set1)))) + && !modified_between_p (SET_DEST (set1), i2, i3) && (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set0)) /* If I3 is a jump, ensure that set0 is a jump so that we do not create invalid RTL. */ @@ -4057,6 +4067,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, && !(GET_CODE (SET_DEST (set0)) == SUBREG && find_reg_note (i2, REG_DEAD, SUBREG_REG (SET_DEST (set0)))) + && !modified_between_p (SET_DEST (set0), i2, i3) && (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set1)) /* If I3 is a jump, ensure that set1 is a jump so that we do not create invalid RTL. */ @@ -5904,8 +5915,9 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, && known_eq (subreg_lowpart_offset (int_mode, int_op0_mode), SUBREG_BYTE (x)) && HWI_COMPUTABLE_MODE_P (int_op0_mode) - && (nonzero_bits (SUBREG_REG (x), int_op0_mode) - & GET_MODE_MASK (int_mode)) == 0) + && ((nonzero_bits (SUBREG_REG (x), int_op0_mode) + & GET_MODE_MASK (int_mode)) == 0) + && !side_effects_p (SUBREG_REG (x))) return CONST0_RTX (int_mode); } @@ -6455,7 +6467,7 @@ simplify_if_then_else (rtx x) pc_rtx, pc_rtx, 0, 0, 0); if (reg_mentioned_p (from, false_rtx)) false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code, - from, false_val), + from, false_val), pc_rtx, pc_rtx, 0, 0, 0); SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx); @@ -7595,6 +7607,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, /* We can't do this if we are widening INNER_MODE (it may not be aligned, for one thing). */ && !paradoxical_subreg_p (tmode, inner_mode) + && known_le (pos + len, GET_MODE_PRECISION (is_mode)) && (inner_mode == tmode || (! mode_dependent_address_p (XEXP (inner, 0), MEM_ADDR_SPACE (inner)) @@ -7737,6 +7750,10 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, && partial_subreg_p (extraction_mode, mode)) extraction_mode = mode; + /* Punt if len is too large for extraction_mode. */ + if (maybe_gt (len, GET_MODE_PRECISION (extraction_mode))) + return NULL_RTX; + if (!MEM_P (inner)) wanted_inner_mode = wanted_inner_reg_mode; else @@ -9294,6 +9311,7 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse) if (COMPARISON_P (cond0) && COMPARISON_P (cond1) + && SCALAR_INT_MODE_P (mode) && ((GET_CODE (cond0) == reversed_comparison_code (cond1, NULL) && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0)) && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1))) @@ -9474,12 +9492,12 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val) if (COMPARISON_P (x)) { if (comparison_dominates_p (cond, code)) - return const_true_rtx; + return VECTOR_MODE_P (GET_MODE (x)) ? x : const_true_rtx; code = reversed_comparison_code (x, NULL); if (code != UNKNOWN && comparison_dominates_p (cond, code)) - return const0_rtx; + return CONST0_RTX (GET_MODE (x)); else return x; } @@ -9522,7 +9540,7 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val) /* We must simplify subreg here, before we lose track of the original inner_mode. */ new_rtx = simplify_subreg (GET_MODE (x), r, - inner_mode, SUBREG_BYTE (x)); + inner_mode, SUBREG_BYTE (x)); if (new_rtx) return new_rtx; else @@ -9547,7 +9565,7 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val) /* We must simplify the zero_extend here, before we lose track of the original inner_mode. */ new_rtx = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x), - r, inner_mode); + r, inner_mode); if (new_rtx) return new_rtx; else @@ -10165,7 +10183,8 @@ reg_nonzero_bits_for_combine (const_rtx x, scalar_int_mode xmode, rsp = ®_stat[REGNO (x)]; if (rsp->last_set_value != 0 && (rsp->last_set_mode == mode - || (GET_MODE_CLASS (rsp->last_set_mode) == MODE_INT + || (REGNO (x) >= FIRST_PSEUDO_REGISTER + && GET_MODE_CLASS (rsp->last_set_mode) == MODE_INT && GET_MODE_CLASS (mode) == MODE_INT)) && ((rsp->last_set_label >= label_tick_ebb_start && rsp->last_set_label < label_tick) @@ -13288,6 +13307,7 @@ record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data) && subreg_lowpart_p (SET_DEST (setter))) record_value_for_reg (dest, record_dead_insn, WORD_REGISTER_OPERATIONS + && word_register_operation_p (SET_SRC (setter)) && paradoxical_subreg_p (SET_DEST (setter)) ? SET_SRC (setter) : gen_lowpart (GET_MODE (dest), diff --git a/contrib/gcc-8.0/gcc/common.opt b/contrib/gcc-8.0/gcc/common.opt index d6ef85928f..b52ef0b38c 100644 --- a/contrib/gcc-8.0/gcc/common.opt +++ b/contrib/gcc-8.0/gcc/common.opt @@ -645,8 +645,8 @@ Common Var(warn_null_dereference) Warning Warn if dereferencing a NULL pointer may lead to erroneous or undefined behavior. Wunsafe-loop-optimizations -Common Var(warn_unsafe_loop_optimizations) Warning -Warn if the loop cannot be optimized due to nontrivial assumptions. +Common Ignore Warning +Does nothing. Preserved for backward compatibility. Wmissing-noreturn Common Warning Alias(Wsuggest-attribute=noreturn) @@ -937,7 +937,11 @@ Driver Undocumented ; ; 12: Corrects the calling convention for classes with only deleted copy/move ; constructors and changes passing/returning of empty records. -; Default in G++ 8. +; Default in G++ 8.1. +; +; 13: Fixes the accidental change in 12 to the calling convention for classes +; with deleted copy constructor and trivial move constructor. +; Default in G++ 8.2. ; ; Additional positive integers will be assigned as new versions of ; the ABI become the default version of the ABI. diff --git a/contrib/gcc-8.0/gcc/common/config/i386/i386-common.c b/contrib/gcc-8.0/gcc/common/config/i386/i386-common.c index 2629ae62a2..3d961320ed 100644 --- a/contrib/gcc-8.0/gcc/common/config/i386/i386-common.c +++ b/contrib/gcc-8.0/gcc/common/config/i386/i386-common.c @@ -59,7 +59,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_FXSR_SET OPTION_MASK_ISA_FXSR #define OPTION_MASK_ISA_XSAVE_SET OPTION_MASK_ISA_XSAVE #define OPTION_MASK_ISA_XSAVEOPT_SET \ - (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE) + (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE_SET) #define OPTION_MASK_ISA_AVX512F_SET \ (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX2_SET) #define OPTION_MASK_ISA_AVX512CD_SET \ @@ -95,9 +95,9 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_PREFETCHWT1_SET OPTION_MASK_ISA_PREFETCHWT1 #define OPTION_MASK_ISA_CLFLUSHOPT_SET OPTION_MASK_ISA_CLFLUSHOPT #define OPTION_MASK_ISA_XSAVES_SET \ - (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE) + (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE_SET) #define OPTION_MASK_ISA_XSAVEC_SET \ - (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE) + (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE_SET) #define OPTION_MASK_ISA_CLWB_SET OPTION_MASK_ISA_CLWB /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same @@ -183,7 +183,8 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA #define OPTION_MASK_ISA_FXSR_UNSET OPTION_MASK_ISA_FXSR #define OPTION_MASK_ISA_XSAVE_UNSET \ - (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET) + (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET \ + | OPTION_MASK_ISA_XSAVES_UNSET | OPTION_MASK_ISA_XSAVEC_UNSET) #define OPTION_MASK_ISA_XSAVEOPT_UNSET OPTION_MASK_ISA_XSAVEOPT #define OPTION_MASK_ISA_AVX2_UNSET \ (OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX512F_UNSET) diff --git a/contrib/gcc-8.0/gcc/config/i386/avx512bitalgintrin.h b/contrib/gcc-8.0/gcc/config/i386/avx512bitalgintrin.h index 54f03eec3e..3a7414adb6 100644 --- a/contrib/gcc-8.0/gcc/config/i386/avx512bitalgintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/avx512bitalgintrin.h @@ -107,7 +107,7 @@ _mm512_bitshuffle_epi64_mask (__m512i __A, __m512i __B) extern __inline __mmask64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_mask_bitshuffle_epi64_mask (__mmask8 __M, __m512i __A, __m512i __B) +_mm512_mask_bitshuffle_epi64_mask (__mmask64 __M, __m512i __A, __m512i __B) { return (__mmask64) __builtin_ia32_vpshufbitqmb512_mask ((__v64qi) __A, (__v64qi) __B, diff --git a/contrib/gcc-8.0/gcc/config/i386/avx512bwintrin.h b/contrib/gcc-8.0/gcc/config/i386/avx512bwintrin.h index bd389fa958..24ad5f1e2a 100644 --- a/contrib/gcc-8.0/gcc/config/i386/avx512bwintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/avx512bwintrin.h @@ -3043,7 +3043,7 @@ _mm512_cmp_epi16_mask (__m512i __X, __m512i __Y, const int __P) extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_mask_cmp_epi8_mask (__mmask32 __U, __m512i __X, __m512i __Y, +_mm512_mask_cmp_epi8_mask (__mmask64 __U, __m512i __X, __m512i __Y, const int __P) { return (__mmask64) __builtin_ia32_cmpb512_mask ((__v64qi) __X, @@ -3081,7 +3081,7 @@ _mm512_cmp_epu16_mask (__m512i __X, __m512i __Y, const int __P) extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_mask_cmp_epu8_mask (__mmask32 __U, __m512i __X, __m512i __Y, +_mm512_mask_cmp_epu8_mask (__mmask64 __U, __m512i __X, __m512i __Y, const int __P) { return (__mmask64) __builtin_ia32_ucmpb512_mask ((__v64qi) __X, diff --git a/contrib/gcc-8.0/gcc/config/i386/avx512fintrin.h b/contrib/gcc-8.0/gcc/config/i386/avx512fintrin.h index ba65acadf8..74184ff8a1 100644 --- a/contrib/gcc-8.0/gcc/config/i386/avx512fintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/avx512fintrin.h @@ -3762,7 +3762,7 @@ _mm512_maskz_fnmsub_round_ps (__mmask16 __U, __m512 __A, __m512 __B, (__m512d)__builtin_ia32_vfmaddsubpd512_mask(A, B, C, -1, R) #define _mm512_mask_fmaddsub_round_pd(A, U, B, C, R) \ - (__m512d)__builtin_ia32_vfmaddpd512_mask(A, B, C, U, R) + (__m512d)__builtin_ia32_vfmaddsubpd512_mask(A, B, C, U, R) #define _mm512_mask3_fmaddsub_round_pd(A, B, C, U, R) \ (__m512d)__builtin_ia32_vfmaddsubpd512_mask3(A, B, C, U, R) @@ -7306,7 +7306,7 @@ _mm512_xor_epi64 (__m512i __A, __m512i __B) extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_mask_xor_epi64 (__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) +_mm512_mask_xor_epi64 (__m512i __W, __mmask8 __U, __m512i __A, __m512i __B) { return (__m512i) __builtin_ia32_pxorq512_mask ((__v8di) __A, (__v8di) __B, @@ -7316,7 +7316,7 @@ _mm512_mask_xor_epi64 (__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_maskz_xor_epi64 (__mmask16 __U, __m512i __A, __m512i __B) +_mm512_maskz_xor_epi64 (__mmask8 __U, __m512i __A, __m512i __B) { return (__m512i) __builtin_ia32_pxorq512_mask ((__v8di) __A, (__v8di) __B, @@ -7727,7 +7727,7 @@ _mm512_mask_abs_ps (__m512 __W, __mmask16 __U, __m512 __A) extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_abs_pd (__m512 __A) +_mm512_abs_pd (__m512d __A) { return (__m512d) _mm512_and_epi64 ((__m512i) __A, _mm512_set1_epi64 (0x7fffffffffffffffLL)); @@ -7735,7 +7735,7 @@ _mm512_abs_pd (__m512 __A) extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_mask_abs_pd (__m512d __W, __mmask8 __U, __m512 __A) +_mm512_mask_abs_pd (__m512d __W, __mmask8 __U, __m512d __A) { return (__m512d) _mm512_mask_and_epi64 ((__m512i) __W, __U, (__m512i) __A, @@ -9544,7 +9544,7 @@ _mm512_cmpneq_epu32_mask (__m512i __X, __m512i __Y) extern __inline __mmask8 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_mask_cmpneq_epi64_mask (__mmask16 __M, __m512i __X, __m512i __Y) +_mm512_mask_cmpneq_epi64_mask (__mmask8 __M, __m512i __X, __m512i __Y) { return (__mmask8) __builtin_ia32_cmpq512_mask ((__v8di) __X, (__v8di) __Y, 4, @@ -10806,22 +10806,22 @@ _mm512_mask_insertf32x4 (__m512 __A, __mmask16 __B, __m512 __C, #define _mm512_maskz_insertf32x4(A, X, Y, C) \ ((__m512) __builtin_ia32_insertf32x4_mask ((__v16sf)(__m512) (X), \ (__v4sf)(__m128) (Y), (int) (C), (__v16sf)_mm512_setzero_ps(), \ - (__mmask8)(A))) + (__mmask16)(A))) #define _mm512_maskz_inserti32x4(A, X, Y, C) \ ((__m512i) __builtin_ia32_inserti32x4_mask ((__v16si)(__m512i) (X), \ (__v4si)(__m128i) (Y), (int) (C), (__v16si)_mm512_setzero_si512 (), \ - (__mmask8)(A))) + (__mmask16)(A))) #define _mm512_mask_insertf32x4(A, B, X, Y, C) \ ((__m512) __builtin_ia32_insertf32x4_mask ((__v16sf)(__m512) (X), \ (__v4sf)(__m128) (Y), (int) (C), (__v16sf)(__m512) (A), \ - (__mmask8)(B))) + (__mmask16)(B))) #define _mm512_mask_inserti32x4(A, B, X, Y, C) \ ((__m512i) __builtin_ia32_inserti32x4_mask ((__v16si)(__m512i) (X), \ (__v4si)(__m128i) (Y), (int) (C), (__v16si)(__m512i) (A), \ - (__mmask8)(B))) + (__mmask16)(B))) #endif extern __inline __m512i diff --git a/contrib/gcc-8.0/gcc/config/i386/avx512vbmi2vlintrin.h b/contrib/gcc-8.0/gcc/config/i386/avx512vbmi2vlintrin.h index b6a3cfd803..b089d3381f 100644 --- a/contrib/gcc-8.0/gcc/config/i386/avx512vbmi2vlintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/avx512vbmi2vlintrin.h @@ -541,7 +541,7 @@ _mm_shldi_epi64 (__m128i __A, __m128i __B, int __C) (__v4si)(__m128i)(B),(int)(C)) #define _mm_mask_shrdi_epi32(A, B, C, D, E) \ ((__m128i) __builtin_ia32_vpshrd_v4si_mask ((__v4si)(__m128i)(C), \ - (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask16)(B)) + (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask8)(B)) #define _mm_maskz_shrdi_epi32(A, B, C, D) \ ((__m128i) __builtin_ia32_vpshrd_v4si_mask ((__v4si)(__m128i)(B), \ (__v4si)(__m128i)(C),(int)(D), \ @@ -601,7 +601,7 @@ _mm_shldi_epi64 (__m128i __A, __m128i __B, int __C) (__v4si)(__m128i)(B),(int)(C)) #define _mm_mask_shldi_epi32(A, B, C, D, E) \ ((__m128i) __builtin_ia32_vpshld_v4si_mask ((__v4si)(__m128i)(C), \ - (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask16)(B)) + (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A),(__mmask8)(B)) #define _mm_maskz_shldi_epi32(A, B, C, D) \ ((__m128i) __builtin_ia32_vpshld_v4si_mask ((__v4si)(__m128i)(B), \ (__v4si)(__m128i)(C),(int)(D), \ diff --git a/contrib/gcc-8.0/gcc/config/i386/avx512vlbwintrin.h b/contrib/gcc-8.0/gcc/config/i386/avx512vlbwintrin.h index c14a86a959..02afce1568 100644 --- a/contrib/gcc-8.0/gcc/config/i386/avx512vlbwintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/avx512vlbwintrin.h @@ -1467,7 +1467,7 @@ _mm256_cmp_epi16_mask (__m256i __X, __m256i __Y, const int __P) extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_epi8_mask (__mmask8 __U, __m128i __X, __m128i __Y, +_mm_mask_cmp_epi8_mask (__mmask16 __U, __m128i __X, __m128i __Y, const int __P) { return (__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi) __X, @@ -1486,7 +1486,7 @@ _mm_cmp_epi8_mask (__m128i __X, __m128i __Y, const int __P) extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmp_epi8_mask (__mmask16 __U, __m256i __X, __m256i __Y, +_mm256_mask_cmp_epi8_mask (__mmask32 __U, __m256i __X, __m256i __Y, const int __P) { return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, @@ -1494,7 +1494,7 @@ _mm256_mask_cmp_epi8_mask (__mmask16 __U, __m256i __X, __m256i __Y, (__mmask32) __U); } -extern __inline __mmask16 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cmp_epi8_mask (__m256i __X, __m256i __Y, const int __P) { @@ -1543,7 +1543,7 @@ _mm256_cmp_epu16_mask (__m256i __X, __m256i __Y, const int __P) extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_epu8_mask (__mmask8 __U, __m128i __X, __m128i __Y, +_mm_mask_cmp_epu8_mask (__mmask16 __U, __m128i __X, __m128i __Y, const int __P) { return (__mmask16) __builtin_ia32_ucmpb128_mask ((__v16qi) __X, @@ -1562,7 +1562,7 @@ _mm_cmp_epu8_mask (__m128i __X, __m128i __Y, const int __P) extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmp_epu8_mask (__mmask16 __U, __m256i __X, __m256i __Y, +_mm256_mask_cmp_epu8_mask (__mmask32 __U, __m256i __X, __m256i __Y, const int __P) { return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, @@ -1570,7 +1570,7 @@ _mm256_mask_cmp_epu8_mask (__mmask16 __U, __m256i __X, __m256i __Y, (__mmask32) __U); } -extern __inline __mmask16 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cmp_epu8_mask (__m256i __X, __m256i __Y, const int __P) { @@ -1998,7 +1998,7 @@ _mm_maskz_slli_epi16 (__mmask8 __U, __m128i __A, int __B) #define _mm_mask_cmp_epi16_mask(M, X, Y, P) \ ((__mmask8) __builtin_ia32_cmpw128_mask ((__v8hi)(__m128i)(X), \ (__v8hi)(__m128i)(Y), (int)(P),\ - (__mmask16)(M))) + (__mmask8)(M))) #define _mm_mask_cmp_epi8_mask(M, X, Y, P) \ ((__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi)(__m128i)(X), \ @@ -2430,7 +2430,7 @@ _mm_maskz_mullo_epi16 (__mmask8 __U, __m128i __A, __m128i __B) extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cvtepi8_epi16 (__m256i __W, __mmask32 __U, __m128i __A) +_mm256_mask_cvtepi8_epi16 (__m256i __W, __mmask16 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovsxbw256_mask ((__v16qi) __A, (__v16hi) __W, @@ -2449,7 +2449,7 @@ _mm256_maskz_cvtepi8_epi16 (__mmask16 __U, __m128i __A) extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvtepi8_epi16 (__m128i __W, __mmask32 __U, __m128i __A) +_mm_mask_cvtepi8_epi16 (__m128i __W, __mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovsxbw128_mask ((__v16qi) __A, (__v8hi) __W, @@ -2468,7 +2468,7 @@ _mm_maskz_cvtepi8_epi16 (__mmask8 __U, __m128i __A) extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cvtepu8_epi16 (__m256i __W, __mmask32 __U, __m128i __A) +_mm256_mask_cvtepu8_epi16 (__m256i __W, __mmask16 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovzxbw256_mask ((__v16qi) __A, (__v16hi) __W, @@ -2487,7 +2487,7 @@ _mm256_maskz_cvtepu8_epi16 (__mmask16 __U, __m128i __A) extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvtepu8_epi16 (__m128i __W, __mmask32 __U, __m128i __A) +_mm_mask_cvtepu8_epi16 (__m128i __W, __mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovzxbw128_mask ((__v16qi) __A, (__v8hi) __W, @@ -4541,148 +4541,148 @@ _mm_mask_cmple_epi16_mask (__mmask8 __M, __m128i __X, __m128i __Y) (__mmask8) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpneq_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpneq_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 4, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 4, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmplt_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmplt_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 1, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 1, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpge_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpge_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 5, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 5, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmple_epu8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmple_epu8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 2, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_ucmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 2, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpneq_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpneq_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 4, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 4, + (__mmask16) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmplt_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmplt_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 1, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 1, + (__mmask16) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpge_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpge_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 5, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 5, + (__mmask16) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmple_epu16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmple_epu16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 2, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_ucmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 2, + (__mmask16) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpneq_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpneq_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 4, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 4, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmplt_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmplt_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 1, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 1, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpge_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpge_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 5, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 5, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmple_epi8_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmple_epi8_mask (__mmask32 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpb256_mask ((__v32qi) __X, - (__v32qi) __Y, 2, - (__mmask8) __M); + return (__mmask32) __builtin_ia32_cmpb256_mask ((__v32qi) __X, + (__v32qi) __Y, 2, + (__mmask32) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpneq_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpneq_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 4, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 4, + (__mmask16) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmplt_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmplt_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 1, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 1, + (__mmask16) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmpge_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmpge_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 5, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 5, + (__mmask16) __M); } -extern __inline __mmask8 +extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_cmple_epi16_mask (__mmask8 __M, __m256i __X, __m256i __Y) +_mm256_mask_cmple_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y) { - return (__mmask8) __builtin_ia32_cmpw256_mask ((__v16hi) __X, - (__v16hi) __Y, 2, - (__mmask8) __M); + return (__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi) __X, + (__v16hi) __Y, 2, + (__mmask16) __M); } #ifdef __DISABLE_AVX512VLBW__ diff --git a/contrib/gcc-8.0/gcc/config/i386/avx512vlintrin.h b/contrib/gcc-8.0/gcc/config/i386/avx512vlintrin.h index 4dfe12fdeb..68b5537845 100644 --- a/contrib/gcc-8.0/gcc/config/i386/avx512vlintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/avx512vlintrin.h @@ -466,7 +466,7 @@ _mm256_maskz_add_pd (__mmask8 __U, __m256d __A, __m256d __B) extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_add_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B) +_mm_mask_add_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { return (__m128) __builtin_ia32_addps128_mask ((__v4sf) __A, (__v4sf) __B, @@ -476,7 +476,7 @@ _mm_mask_add_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B) extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_add_ps (__mmask16 __U, __m128 __A, __m128 __B) +_mm_maskz_add_ps (__mmask8 __U, __m128 __A, __m128 __B) { return (__m128) __builtin_ia32_addps128_mask ((__v4sf) __A, (__v4sf) __B, @@ -487,7 +487,7 @@ _mm_maskz_add_ps (__mmask16 __U, __m128 __A, __m128 __B) extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_add_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B) +_mm256_mask_add_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { return (__m256) __builtin_ia32_addps256_mask ((__v8sf) __A, (__v8sf) __B, @@ -497,7 +497,7 @@ _mm256_mask_add_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B) extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_add_ps (__mmask16 __U, __m256 __A, __m256 __B) +_mm256_maskz_add_ps (__mmask8 __U, __m256 __A, __m256 __B) { return (__m256) __builtin_ia32_addps256_mask ((__v8sf) __A, (__v8sf) __B, @@ -551,7 +551,7 @@ _mm256_maskz_sub_pd (__mmask8 __U, __m256d __A, __m256d __B) extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sub_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B) +_mm_mask_sub_ps (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) { return (__m128) __builtin_ia32_subps128_mask ((__v4sf) __A, (__v4sf) __B, @@ -561,7 +561,7 @@ _mm_mask_sub_ps (__m128 __W, __mmask16 __U, __m128 __A, __m128 __B) extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sub_ps (__mmask16 __U, __m128 __A, __m128 __B) +_mm_maskz_sub_ps (__mmask8 __U, __m128 __A, __m128 __B) { return (__m128) __builtin_ia32_subps128_mask ((__v4sf) __A, (__v4sf) __B, @@ -572,7 +572,7 @@ _mm_maskz_sub_ps (__mmask16 __U, __m128 __A, __m128 __B) extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_sub_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B) +_mm256_mask_sub_ps (__m256 __W, __mmask8 __U, __m256 __A, __m256 __B) { return (__m256) __builtin_ia32_subps256_mask ((__v8sf) __A, (__v8sf) __B, @@ -582,7 +582,7 @@ _mm256_mask_sub_ps (__m256 __W, __mmask16 __U, __m256 __A, __m256 __B) extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_sub_ps (__mmask16 __U, __m256 __A, __m256 __B) +_mm256_maskz_sub_ps (__mmask8 __U, __m256 __A, __m256 __B) { return (__m256) __builtin_ia32_subps256_mask ((__v8sf) __A, (__v8sf) __B, @@ -1320,7 +1320,7 @@ _mm256_mask_cvtepi32_ps (__m256 __W, __mmask8 __U, __m256i __A) extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_cvtepi32_ps (__mmask16 __U, __m256i __A) +_mm256_maskz_cvtepi32_ps (__mmask8 __U, __m256i __A) { return (__m256) __builtin_ia32_cvtdq2ps256_mask ((__v8si) __A, (__v8sf) @@ -1339,7 +1339,7 @@ _mm_mask_cvtepi32_ps (__m128 __W, __mmask8 __U, __m128i __A) extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvtepi32_ps (__mmask16 __U, __m128i __A) +_mm_maskz_cvtepi32_ps (__mmask8 __U, __m128i __A) { return (__m128) __builtin_ia32_cvtdq2ps128_mask ((__v4si) __A, (__v4sf) diff --git a/contrib/gcc-8.0/gcc/config/i386/emmintrin.h b/contrib/gcc-8.0/gcc/config/i386/emmintrin.h index b940a39d27..040470f51d 100644 --- a/contrib/gcc-8.0/gcc/config/i386/emmintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/emmintrin.h @@ -45,6 +45,7 @@ typedef unsigned int __v4su __attribute__ ((__vector_size__ (16))); typedef short __v8hi __attribute__ ((__vector_size__ (16))); typedef unsigned short __v8hu __attribute__ ((__vector_size__ (16))); typedef char __v16qi __attribute__ ((__vector_size__ (16))); +typedef signed char __v16qs __attribute__ ((__vector_size__ (16))); typedef unsigned char __v16qu __attribute__ ((__vector_size__ (16))); /* The Intel API is flexible enough that we must allow aliasing with other @@ -1295,7 +1296,7 @@ _mm_xor_si128 (__m128i __A, __m128i __B) extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_cmpeq_epi8 (__m128i __A, __m128i __B) { - return (__m128i) ((__v16qi)__A == (__v16qi)__B); + return (__m128i) ((__v16qs)__A == (__v16qs)__B); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -1313,7 +1314,7 @@ _mm_cmpeq_epi32 (__m128i __A, __m128i __B) extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_cmplt_epi8 (__m128i __A, __m128i __B) { - return (__m128i) ((__v16qi)__A < (__v16qi)__B); + return (__m128i) ((__v16qs)__A < (__v16qs)__B); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -1331,7 +1332,7 @@ _mm_cmplt_epi32 (__m128i __A, __m128i __B) extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_cmpgt_epi8 (__m128i __A, __m128i __B) { - return (__m128i) ((__v16qi)__A > (__v16qi)__B); + return (__m128i) ((__v16qs)__A > (__v16qs)__B); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) diff --git a/contrib/gcc-8.0/gcc/config/i386/i386-builtin.def b/contrib/gcc-8.0/gcc/config/i386/i386-builtin.def index 1b9c63a16d..c14f7ef3ce 100644 --- a/contrib/gcc-8.0/gcc/config/i386/i386-builtin.def +++ b/contrib/gcc-8.0/gcc/config/i386/i386-builtin.def @@ -90,6 +90,7 @@ BDESC_END (PCMPISTR, SPECIAL_ARGS) BDESC_FIRST (special_args, SPECIAL_ARGS, 0, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID) BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED) +BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT) BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID) /* 80387 (for use internally for atomic compound assignment). */ @@ -427,7 +428,6 @@ BDESC_END (SPECIAL_ARGS, ARGS) BDESC_FIRST (args, ARGS, 0, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT) BDESC (OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64) -BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT) BDESC (0, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT) BDESC (0, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT) BDESC (0, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT) diff --git a/contrib/gcc-8.0/gcc/config/i386/i386.c b/contrib/gcc-8.0/gcc/config/i386/i386.c index 6a2141e48d..7732f882f7 100644 --- a/contrib/gcc-8.0/gcc/config/i386/i386.c +++ b/contrib/gcc-8.0/gcc/config/i386/i386.c @@ -91,6 +91,8 @@ along with GCC; see the file COPYING3. If not see #include "ipa-prop.h" #include "ipa-fnsummary.h" #include "wide-int-bitmask.h" +#include "debug.h" +#include "dwarf2out.h" /* This file should be included last. */ #include "target-def.h" @@ -139,7 +141,6 @@ const struct processor_costs *ix86_cost = NULL; #define m_NEHALEM (HOST_WIDE_INT_1U<decl))) && !cgraph_node::get (cfun->decl)->only_called_directly_p ()) { - cet_eb = gen_nop_endbr (); + /* Queue ENDBR insertion to x86_function_profiler. */ + if (crtl->profile && flag_fentry) + cfun->machine->endbr_queued_at_entrance = true; + else + { + cet_eb = gen_nop_endbr (); - bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; - insn = BB_HEAD (bb); - emit_insn_before (cet_eb, insn); + bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; + insn = BB_HEAD (bb); + emit_insn_before (cet_eb, insn); + } } bb = 0; @@ -4845,8 +4856,14 @@ ix86_option_override_internal (bool main_args_p, /* Handle stack protector */ if (!opts_set->x_ix86_stack_protector_guard) - opts->x_ix86_stack_protector_guard - = TARGET_HAS_BIONIC ? SSP_GLOBAL : SSP_TLS; + { +#ifdef TARGET_THREAD_SSP_OFFSET + if (!TARGET_HAS_BIONIC) + opts->x_ix86_stack_protector_guard = SSP_TLS; + else +#endif + opts->x_ix86_stack_protector_guard = SSP_GLOBAL; + } #ifdef TARGET_THREAD_SSP_OFFSET ix86_stack_protector_guard_offset = TARGET_THREAD_SSP_OFFSET; @@ -8190,7 +8207,7 @@ construct_container (machine_mode mode, machine_mode orig_mode, case X86_64_SSEDF_CLASS: if (mode != BLKmode) return gen_reg_or_parallel (mode, orig_mode, - SSE_REGNO (sse_regno)); + GET_SSE_REGNO (sse_regno)); break; case X86_64_X87_CLASS: case X86_64_COMPLEX_X87_CLASS: @@ -8206,7 +8223,7 @@ construct_container (machine_mode mode, machine_mode orig_mode, && regclass[1] == X86_64_SSEUP_CLASS && mode != BLKmode) return gen_reg_or_parallel (mode, orig_mode, - SSE_REGNO (sse_regno)); + GET_SSE_REGNO (sse_regno)); if (n == 4 && regclass[0] == X86_64_SSE_CLASS && regclass[1] == X86_64_SSEUP_CLASS @@ -8214,7 +8231,7 @@ construct_container (machine_mode mode, machine_mode orig_mode, && regclass[3] == X86_64_SSEUP_CLASS && mode != BLKmode) return gen_reg_or_parallel (mode, orig_mode, - SSE_REGNO (sse_regno)); + GET_SSE_REGNO (sse_regno)); if (n == 8 && regclass[0] == X86_64_SSE_CLASS && regclass[1] == X86_64_SSEUP_CLASS @@ -8226,7 +8243,7 @@ construct_container (machine_mode mode, machine_mode orig_mode, && regclass[7] == X86_64_SSEUP_CLASS && mode != BLKmode) return gen_reg_or_parallel (mode, orig_mode, - SSE_REGNO (sse_regno)); + GET_SSE_REGNO (sse_regno)); if (n == 2 && regclass[0] == X86_64_X87_CLASS && regclass[1] == X86_64_X87UP_CLASS) @@ -8235,9 +8252,22 @@ construct_container (machine_mode mode, machine_mode orig_mode, if (n == 2 && regclass[0] == X86_64_INTEGER_CLASS && regclass[1] == X86_64_INTEGER_CLASS - && (mode == CDImode || mode == TImode) + && (mode == CDImode || mode == TImode || mode == BLKmode) && intreg[0] + 1 == intreg[1]) - return gen_rtx_REG (mode, intreg[0]); + { + if (mode == BLKmode) + { + /* Use TImode for BLKmode values in 2 integer registers. */ + exp[0] = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (TImode, intreg[0]), + GEN_INT (0)); + ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1)); + XVECEXP (ret, 0, 0) = exp[0]; + return ret; + } + else + return gen_rtx_REG (mode, intreg[0]); + } /* Otherwise figure out the entries of the PARALLEL. */ for (i = 0; i < n; i++) @@ -8273,7 +8303,7 @@ construct_container (machine_mode mode, machine_mode orig_mode, exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (SFmode, - SSE_REGNO (sse_regno)), + GET_SSE_REGNO (sse_regno)), GEN_INT (i*8)); sse_regno++; break; @@ -8281,7 +8311,7 @@ construct_container (machine_mode mode, machine_mode orig_mode, exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (DFmode, - SSE_REGNO (sse_regno)), + GET_SSE_REGNO (sse_regno)), GEN_INT (i*8)); sse_regno++; break; @@ -8327,7 +8357,7 @@ construct_container (machine_mode mode, machine_mode orig_mode, exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (tmpmode, - SSE_REGNO (sse_regno)), + GET_SSE_REGNO (sse_regno)), GEN_INT (pos*8)); sse_regno++; break; @@ -9763,7 +9793,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum) set_mem_alias_set (mem, set); set_mem_align (mem, GET_MODE_ALIGNMENT (smode)); - emit_move_insn (mem, gen_rtx_REG (smode, SSE_REGNO (i))); + emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i))); } emit_label (label); @@ -10992,6 +11022,23 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix, ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); + /* The above call insn pushed a word to stack. Adjust CFI info. */ + if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ()) + { + if (! dwarf2out_do_cfi_asm ()) + { + dw_cfi_ref xcfi = ggc_cleared_alloc (); + xcfi->dw_cfi_opc = DW_CFA_advance_loc4; + xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2); + vec_safe_push (cfun->fde->dw_fde_cfi, xcfi); + } + dw_cfi_ref xcfi = ggc_cleared_alloc (); + xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset; + xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD; + vec_safe_push (cfun->fde->dw_fde_cfi, xcfi); + dwarf2out_emit_cfi (xcfi); + } + if (regno != INVALID_REGNUM) { /* MOV. */ @@ -11675,10 +11722,16 @@ ix86_compute_frame_layout (void) /* 64-bit MS ABI seem to require stack alignment to be always 16, except for function prologues, leaf functions and when the defult incoming stack boundary is overriden at command line or via - force_align_arg_pointer attribute. */ - if ((TARGET_64BIT_MS_ABI && crtl->preferred_stack_boundary < 128) + force_align_arg_pointer attribute. + + Darwin's ABI specifies 128b alignment for both 32 and 64 bit variants + at call sites, including profile function calls. + */ + if (((TARGET_64BIT_MS_ABI || TARGET_MACHO) + && crtl->preferred_stack_boundary < 128) && (!crtl->is_leaf || cfun->calls_alloca != 0 || ix86_current_function_calls_tls_descriptor + || (TARGET_MACHO && crtl->profile) || ix86_incoming_stack_boundary < 128)) { crtl->preferred_stack_boundary = 128; @@ -13328,7 +13381,7 @@ ix86_finalize_stack_frame_flags (void) is used, but in the end nothing that needed the stack alignment had been spilled nor stack access, clear frame_pointer_needed and say we don't need stack realignment. */ - if ((stack_realign || !flag_omit_frame_pointer) + if ((stack_realign || (!flag_omit_frame_pointer && optimize)) && frame_pointer_needed && crtl->is_leaf && crtl->sp_is_unchanging @@ -13435,12 +13488,14 @@ ix86_finalize_stack_frame_flags (void) recompute_frame_layout_p = true; } } - else if (crtl->max_used_stack_slot_alignment - > crtl->preferred_stack_boundary) + else if (crtl->max_used_stack_slot_alignment >= 128) { - /* We don't need to realign stack. But we still need to keep - stack frame properly aligned to satisfy the largest alignment - of stack slots. */ + /* We don't need to realign stack. max_used_stack_alignment is + used to decide how stack frame should be aligned. This is + independent of any psABIs nor 32-bit vs 64-bit. It is always + safe to compute max_used_stack_alignment. We compute it only + if 128-bit aligned load/store may be generated on misaligned + stack slot which will lead to segfault. */ if (ix86_find_max_used_stack_alignment (stack_alignment, true)) cfun->machine->max_used_stack_alignment = stack_alignment / BITS_PER_UNIT; @@ -14033,8 +14088,9 @@ ix86_expand_prologue (void) } m->fs.sp_offset += allocate; - /* Use stack_pointer_rtx for relative addressing so that code - works for realigned stack, too. */ + /* Use stack_pointer_rtx for relative addressing so that code works for + realigned stack. But this means that we need a blockage to prevent + stores based on the frame pointer from being scheduled before. */ if (r10_live && eax_live) { t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax); @@ -14043,6 +14099,7 @@ ix86_expand_prologue (void) t = plus_constant (Pmode, t, UNITS_PER_WORD); emit_move_insn (gen_rtx_REG (word_mode, AX_REG), gen_frame_mem (word_mode, t)); + emit_insn (gen_memory_blockage ()); } else if (eax_live || r10_live) { @@ -14050,6 +14107,7 @@ ix86_expand_prologue (void) emit_move_insn (gen_rtx_REG (word_mode, (eax_live ? AX_REG : R10_REG)), gen_frame_mem (word_mode, t)); + emit_insn (gen_memory_blockage ()); } } gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset); @@ -24011,7 +24069,7 @@ ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0, return true; } -/* Expand an sse vector comparison. Return the register with the result. */ +/* Expand an SSE comparison. Return the register with the result. */ static rtx ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1, @@ -24036,9 +24094,12 @@ ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1, else cmp_mode = cmp_ops_mode; - cmp_op0 = force_reg (cmp_ops_mode, cmp_op0); - if (!nonimmediate_operand (cmp_op1, cmp_ops_mode)) + + int (*op1_predicate)(rtx, machine_mode) + = VECTOR_MODE_P (cmp_ops_mode) ? vector_operand : nonimmediate_operand; + + if (!op1_predicate (cmp_op1, cmp_ops_mode)) cmp_op1 = force_reg (cmp_ops_mode, cmp_op1); if (optimize @@ -24158,7 +24219,7 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false) rtx (*gen) (rtx, rtx, rtx, rtx) = NULL; rtx d = dest; - if (!nonimmediate_operand (op_true, mode)) + if (!vector_operand (op_true, mode)) op_true = force_reg (mode, op_true); op_false = force_reg (mode, op_false); @@ -29982,6 +30043,10 @@ ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type) if (!TYPE_EMPTY_P (type)) return; + /* Don't warn if the function isn't visible outside of the TU. */ + if (cum->decl && !TREE_PUBLIC (cum->decl)) + return; + const_tree ctx = get_ultimate_context (cum->decl); if (ctx != NULL_TREE && !TRANSLATION_UNIT_WARN_EMPTY_P (ctx)) @@ -37042,7 +37107,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_RDPID: - op0 = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); + op0 = gen_reg_rtx (word_mode); if (TARGET_64BIT) { @@ -37051,18 +37116,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, } else insn = gen_rdpid (op0); + emit_insn (insn); - if (target == 0) - { - /* mode is VOIDmode if __builtin_rdpid has been called - without lhs. */ - if (mode == VOIDmode) - return target; - target = gen_reg_rtx (mode); - } + if (target == 0 + || !register_operand (target, SImode)) + target = gen_reg_rtx (SImode); + emit_move_insn (target, op0); return target; + case IX86_BUILTIN_RDPMC: case IX86_BUILTIN_RDTSC: case IX86_BUILTIN_RDTSCP: @@ -37121,14 +37184,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, emit_move_insn (gen_rtx_MEM (SImode, op4), op2); } - if (target == 0) - { - /* mode is VOIDmode if __builtin_rd* has been called - without lhs. */ - if (mode == VOIDmode) - return target; - target = gen_reg_rtx (mode); - } + if (target == 0 + || !register_operand (target, DImode)) + target = gen_reg_rtx (DImode); if (TARGET_64BIT) { @@ -37217,25 +37275,23 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, if (!REG_P (op0)) op0 = copy_to_mode_reg (SImode, op0); + op1 = force_reg (DImode, op1); + if (TARGET_64BIT) { op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32), NULL, 1, OPTAB_DIRECT); + icode = CODE_FOR_xsetbv_rex64; + op2 = gen_lowpart (SImode, op2); op1 = gen_lowpart (SImode, op1); - if (!REG_P (op1)) - op1 = copy_to_mode_reg (SImode, op1); - if (!REG_P (op2)) - op2 = copy_to_mode_reg (SImode, op2); - icode = CODE_FOR_xsetbv_rex64; pat = GEN_FCN (icode) (op0, op1, op2); } else { - if (!REG_P (op1)) - op1 = copy_to_mode_reg (DImode, op1); icode = CODE_FOR_xsetbv; + pat = GEN_FCN (icode) (op0, op1); } if (pat) @@ -37387,6 +37443,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, unsigned char lsb_index = INTVAL (op1) & 0xFF; op1 = GEN_INT (length); op2 = GEN_INT (lsb_index); + + mode1 = insn_data[icode].operand[1].mode; + if (!insn_data[icode].operand[1].predicate (op0, mode1)) + op0 = copy_to_mode_reg (mode1, op0); + + mode0 = insn_data[icode].operand[0].mode; + if (target == 0 + || !register_operand (target, mode0)) + target = gen_reg_rtx (mode0); + pat = GEN_FCN (icode) (target, op0, op1, op2); if (pat) emit_insn (pat); @@ -41978,6 +42044,10 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) { const char *mcount_name = (flag_fentry ? MCOUNT_NAME_BEFORE_PROLOGUE : MCOUNT_NAME); + + if (cfun->machine->endbr_queued_at_entrance) + fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32"); + if (TARGET_64BIT) { #ifndef NO_PROFILE_COUNTERS @@ -50684,7 +50754,9 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node, case E_DFmode: /* case E_SCmode: */ /* case E_DCmode: */ - break; + if (!AGGREGATE_TYPE_P (ret_type)) + break; + /* FALLTHRU */ default: warning_at (DECL_SOURCE_LOCATION (node->decl), 0, "unsupported return type %qT for simd", ret_type); @@ -50693,25 +50765,34 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node, tree t; int i; + tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl)); + bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE); - for (t = DECL_ARGUMENTS (node->decl), i = 0; t; t = DECL_CHAIN (t), i++) - /* FIXME: Shouldn't we allow such arguments if they are uniform? */ - switch (TYPE_MODE (TREE_TYPE (t))) - { - case E_QImode: - case E_HImode: - case E_SImode: - case E_DImode: - case E_SFmode: - case E_DFmode: - /* case E_SCmode: */ - /* case E_DCmode: */ - break; - default: - warning_at (DECL_SOURCE_LOCATION (node->decl), 0, - "unsupported argument type %qT for simd", TREE_TYPE (t)); - return 0; - } + for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0; + t && t != void_list_node; t = TREE_CHAIN (t), i++) + { + tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t); + switch (TYPE_MODE (arg_type)) + { + case E_QImode: + case E_HImode: + case E_SImode: + case E_DImode: + case E_SFmode: + case E_DFmode: + /* case E_SCmode: */ + /* case E_DCmode: */ + if (!AGGREGATE_TYPE_P (arg_type)) + break; + /* FALLTHRU */ + default: + if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM) + break; + warning_at (DECL_SOURCE_LOCATION (node->decl), 0, + "unsupported argument type %qT for simd", arg_type); + return 0; + } + } if (!TREE_PUBLIC (node->decl)) { @@ -51286,9 +51367,7 @@ ix86_expand_divmod_libfunc (rtx libfunc, machine_mode mode, rtx rem = assign_386_stack_local (mode, SLOT_TEMP); rtx quot = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL, - mode, - op0, GET_MODE (op0), - op1, GET_MODE (op1), + mode, op0, mode, op1, mode, XEXP (rem, 0), Pmode); *quot_p = quot; *rem_p = rem; diff --git a/contrib/gcc-8.0/gcc/config/i386/i386.h b/contrib/gcc-8.0/gcc/config/i386/i386.h index 795ad2a322..bcefa0ebd4 100644 --- a/contrib/gcc-8.0/gcc/config/i386/i386.h +++ b/contrib/gcc-8.0/gcc/config/i386/i386.h @@ -790,8 +790,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define PARM_BOUNDARY BITS_PER_WORD /* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY \ - (TARGET_64BIT && ix86_abi == MS_ABI ? 128 : BITS_PER_WORD) +#define STACK_BOUNDARY (TARGET_64BIT_MS_ABI ? 128 : BITS_PER_WORD) /* Stack boundary of the main function guaranteed by OS. */ #define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32) @@ -1536,10 +1535,10 @@ enum reg_class #define FIRST_FLOAT_REG FIRST_STACK_REG #define STACK_TOP_P(X) (REG_P (X) && REGNO (X) == FIRST_FLOAT_REG) -#define SSE_REGNO(N) \ - ((N) < 8 ? FIRST_SSE_REG + (N) \ - : (N) <= LAST_REX_SSE_REG ? (FIRST_REX_SSE_REG + (N) - 8) \ - : (FIRST_EXT_REX_SSE_REG + (N) - 16)) +#define GET_SSE_REGNO(N) \ + ((N) < 8 ? FIRST_SSE_REG + (N) \ + : (N) < 16 ? FIRST_REX_SSE_REG + (N) - 8 \ + : FIRST_EXT_REX_SSE_REG + (N) - 16) /* The class value for index registers, and the one for base regs. */ @@ -2635,6 +2634,9 @@ struct GTY(()) machine_function { /* Nonzero if the function places outgoing arguments on stack. */ BOOL_BITFIELD outgoing_args_on_stack : 1; + /* If true, ENDBR is queued at function entrance. */ + BOOL_BITFIELD endbr_queued_at_entrance : 1; + /* The largest alignment, in bytes, of stack slot actually used. */ unsigned int max_used_stack_alignment; diff --git a/contrib/gcc-8.0/gcc/config/i386/i386.md b/contrib/gcc-8.0/gcc/config/i386/i386.md index ad9ccf9d1d..7691160c0c 100644 --- a/contrib/gcc-8.0/gcc/config/i386/i386.md +++ b/contrib/gcc-8.0/gcc/config/i386/i386.md @@ -12481,6 +12481,7 @@ "(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[4]) && ! reg_set_p (operands[3], operands[4]) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 5) (match_dup 0)) @@ -12506,6 +12507,7 @@ || operands_match_p (operands[2], operands[4])) && ! reg_overlap_mentioned_p (operands[4], operands[0]) && ! reg_overlap_mentioned_p (operands[4], operands[1]) + && ! reg_overlap_mentioned_p (operands[4], operands[5]) && ! reg_set_p (operands[4], operands[5]) && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) && peep2_regno_dead_p (0, FLAGS_REG)" @@ -12555,6 +12557,7 @@ "(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[4]) && ! reg_set_p (operands[3], operands[4]) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 5) (match_dup 0)) @@ -12581,6 +12584,7 @@ || operands_match_p (operands[2], operands[4])) && ! reg_overlap_mentioned_p (operands[4], operands[0]) && ! reg_overlap_mentioned_p (operands[4], operands[1]) + && ! reg_overlap_mentioned_p (operands[4], operands[5]) && ! reg_set_p (operands[4], operands[5]) && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) && peep2_regno_dead_p (0, FLAGS_REG)" @@ -13341,7 +13345,10 @@ stack address we wish to restore. */ tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD); - tmp = gen_rtx_MEM (Pmode, tmp); + /* Return address is always in word_mode. */ + tmp = gen_rtx_MEM (word_mode, tmp); + if (GET_MODE (ra) != word_mode) + ra = convert_to_mode (word_mode, ra, 1); emit_move_insn (tmp, ra); emit_jump_insn (gen_eh_return_internal ()); @@ -16350,7 +16357,7 @@ (define_insn "sse4_1_round2" [(set (match_operand:MODEF 0 "register_operand" "=x,v") - (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v") + (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm") (match_operand:SI 2 "const_0_to_15_operand" "n,n")] UNSPEC_ROUND))] "TARGET_SSE4_1" @@ -16946,12 +16953,19 @@ FIST_ROUNDING)) (clobber (reg:CC FLAGS_REG))])] "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH - && !flag_trapping_math" + && (TARGET_SSE4_1 || !flag_trapping_math)" { - if (TARGET_64BIT && optimize_insn_for_size_p ()) - FAIL; + if (TARGET_SSE4_1) + { + rtx tmp = gen_reg_rtx (mode); - if (ROUND_ == ROUND_FLOOR) + emit_insn (gen_sse4_1_round2 + (tmp, operands[1], GEN_INT (ROUND_ + | ROUND_NO_EXC))); + emit_insn (gen_fix_trunc2 + (operands[0], tmp)); + } + else if (ROUND_ == ROUND_FLOOR) ix86_expand_lfloorceil (operands[0], operands[1], true); else if (ROUND_ == ROUND_CEIL) ix86_expand_lfloorceil (operands[0], operands[1], false); @@ -19073,6 +19087,37 @@ const0_rtx); }) +;; Likewise for cmpelim optimized pattern. +(define_peephole2 + [(set (match_operand:SWI 0 "register_operand") + (match_operand:SWI 1 "memory_operand")) + (parallel [(set (reg FLAGS_REG) + (compare (match_operator:SWI 3 "plusminuslogic_operator" + [(match_dup 0) + (match_operand:SWI 2 "")]) + (const_int 0))) + (set (match_dup 0) (match_dup 3))]) + (set (match_dup 1) (match_dup 0))] + "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) + && peep2_reg_dead_p (3, operands[0]) + && !reg_overlap_mentioned_p (operands[0], operands[1]) + && !reg_overlap_mentioned_p (operands[0], operands[2]) + && ix86_match_ccmode (peep2_next_insn (1), + (GET_CODE (operands[3]) == PLUS + || GET_CODE (operands[3]) == MINUS) + ? CCGOCmode : CCNOmode)" + [(parallel [(set (match_dup 4) (match_dup 6)) + (set (match_dup 1) (match_dup 5))])] +{ + operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0)); + operands[5] + = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), + copy_rtx (operands[1]), operands[2]); + operands[6] + = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]), + const0_rtx); +}) + ;; Likewise for instances where we have a lea pattern. (define_peephole2 [(set (match_operand:SWI 0 "register_operand") @@ -19116,7 +19161,7 @@ (set (match_dup 1) (match_dup 0)) (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) - && GET_CODE (operands[2]) != MINUS + && COMMUTATIVE_ARITH_P (operands[2]) && peep2_reg_dead_p (3, operands[0]) && !reg_overlap_mentioned_p (operands[0], operands[1]) && ix86_match_ccmode (peep2_next_insn (2), @@ -19136,6 +19181,34 @@ const0_rtx); }) +;; Likewise for cmpelim optimized pattern. +(define_peephole2 + [(parallel [(set (reg FLAGS_REG) + (compare (match_operator:SWI 2 "plusminuslogic_operator" + [(match_operand:SWI 0 "register_operand") + (match_operand:SWI 1 "memory_operand")]) + (const_int 0))) + (set (match_dup 0) (match_dup 2))]) + (set (match_dup 1) (match_dup 0))] + "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) + && COMMUTATIVE_ARITH_P (operands[2]) + && peep2_reg_dead_p (2, operands[0]) + && !reg_overlap_mentioned_p (operands[0], operands[1]) + && ix86_match_ccmode (peep2_next_insn (0), + GET_CODE (operands[2]) == PLUS + ? CCGOCmode : CCNOmode)" + [(parallel [(set (match_dup 3) (match_dup 5)) + (set (match_dup 1) (match_dup 4))])] +{ + operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0)); + operands[4] + = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), + copy_rtx (operands[1]), operands[0]); + operands[5] + = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]), + const0_rtx); +}) + (define_peephole2 [(set (match_operand:SWI12 0 "register_operand") (match_operand:SWI12 1 "memory_operand")) @@ -19701,7 +19774,7 @@ (define_expand "stack_protect_set" [(match_operand 0 "memory_operand") (match_operand 1 "memory_operand")] - "TARGET_SSP_TLS_GUARD" + "" { rtx (*insn)(rtx, rtx); @@ -19719,7 +19792,7 @@ UNSPEC_SP_SET)) (set (match_scratch:PTR 2 "=&r") (const_int 0)) (clobber (reg:CC FLAGS_REG))] - "TARGET_SSP_TLS_GUARD" + "" "mov{}\t{%1, %2|%2, %1}\;mov{}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" [(set_attr "type" "multi")]) @@ -19727,7 +19800,7 @@ [(match_operand 0 "memory_operand") (match_operand 1 "memory_operand") (match_operand 2)] - "TARGET_SSP_TLS_GUARD" + "" { rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); @@ -19750,7 +19823,7 @@ (match_operand:PTR 2 "memory_operand" "m")] UNSPEC_SP_TEST)) (clobber (match_scratch:PTR 3 "=&r"))] - "TARGET_SSP_TLS_GUARD" + "" "mov{}\t{%1, %3|%3, %1}\;xor{}\t{%2, %3|%3, %2}" [(set_attr "type" "multi")]) diff --git a/contrib/gcc-8.0/gcc/config/i386/predicates.md b/contrib/gcc-8.0/gcc/config/i386/predicates.md index f6cdc86fc5..211f7eea40 100644 --- a/contrib/gcc-8.0/gcc/config/i386/predicates.md +++ b/contrib/gcc-8.0/gcc/config/i386/predicates.md @@ -182,7 +182,7 @@ rtx op1 = XEXP (XEXP (op, 0), 0); rtx op2 = XEXP (XEXP (op, 0), 1); - if (ix86_cmodel == CM_LARGE) + if (ix86_cmodel == CM_LARGE && GET_CODE (op1) != UNSPEC) return false; if (!CONST_INT_P (op2)) return false; @@ -1517,7 +1517,7 @@ if (GET_CODE (elt) != SET || GET_CODE (SET_DEST (elt)) != REG || GET_MODE (SET_DEST (elt)) != V8SImode - || REGNO (SET_DEST (elt)) != SSE_REGNO (i) + || REGNO (SET_DEST (elt)) != GET_SSE_REGNO (i) || SET_SRC (elt) != CONST0_RTX (V8SImode)) return false; } diff --git a/contrib/gcc-8.0/gcc/config/i386/sse.md b/contrib/gcc-8.0/gcc/config/i386/sse.md index 640971d5e1..d5cab80f60 100644 --- a/contrib/gcc-8.0/gcc/config/i386/sse.md +++ b/contrib/gcc-8.0/gcc/config/i386/sse.md @@ -21,6 +21,9 @@ ;; SSE UNSPEC_MOVNT + ;; SSE2 + UNSPEC_MOVDI_TO_SSE + ;; SSE3 UNSPEC_LDDQU @@ -1224,10 +1227,10 @@ ;; from there. (define_insn_and_split "movdi_to_sse" - [(parallel - [(set (match_operand:V4SI 0 "register_operand" "=?x,x") - (subreg:V4SI (match_operand:DI 1 "nonimmediate_operand" "r,m") 0)) - (clobber (match_scratch:V4SI 2 "=&x,X"))])] + [(set (match_operand:V4SI 0 "register_operand" "=?x,x") + (unspec:V4SI [(match_operand:DI 1 "nonimmediate_operand" "r,m")] + UNSPEC_MOVDI_TO_SSE)) + (clobber (match_scratch:V4SI 2 "=&x,X"))] "!TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC" "#" "&& reload_completed" @@ -1245,11 +1248,8 @@ operands[2])); } else if (memory_operand (operands[1], DImode)) - { - rtx tmp = gen_reg_rtx (V2DImode); - emit_insn (gen_vec_concatv2di (tmp, operands[1], const0_rtx)); - emit_move_insn (operands[0], gen_lowpart (V4SImode, tmp)); - } + emit_insn (gen_vec_concatv2di (gen_lowpart (V2DImode, operands[0]), + operands[1], const0_rtx)); else gcc_unreachable (); DONE; @@ -4517,7 +4517,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{q}\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "sseicvt") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -4720,37 +4720,49 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define_insn "sse2_cvtpi2pd" - [(set (match_operand:V2DF 0 "register_operand" "=x,x") - (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))] + [(set (match_operand:V2DF 0 "register_operand" "=v,x") + (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "vBm,?!y")))] "TARGET_SSE2" - "cvtpi2pd\t{%1, %0|%0, %1}" + "@ + %vcvtdq2pd\t{%1, %0|%0, %1} + cvtpi2pd\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") - (set_attr "unit" "mmx,*") - (set_attr "prefix_data16" "1,*") + (set_attr "unit" "*,mmx") + (set_attr "prefix_data16" "*,1") + (set_attr "prefix" "maybe_vex,*") (set_attr "mode" "V2DF")]) (define_insn "sse2_cvtpd2pi" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")] + [(set (match_operand:V2SI 0 "register_operand" "=v,?!y") + (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "vBm,xm")] UNSPEC_FIX_NOTRUNC))] "TARGET_SSE2" - "cvtpd2pi\t{%1, %0|%0, %1}" + "@ + * return TARGET_AVX ? \"vcvtpd2dq{x}\t{%1, %0|%0, %1}\" : \"cvtpd2dq\t{%1, %0|%0, %1}\"; + cvtpd2pi\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") - (set_attr "unit" "mmx") + (set_attr "unit" "*,mmx") + (set_attr "amdfam10_decode" "double") + (set_attr "athlon_decode" "vector") (set_attr "bdver1_decode" "double") - (set_attr "btver2_decode" "direct") - (set_attr "prefix_data16" "1") - (set_attr "mode" "DI")]) + (set_attr "prefix_data16" "*,1") + (set_attr "prefix" "maybe_vex,*") + (set_attr "mode" "TI")]) (define_insn "sse2_cvttpd2pi" - [(set (match_operand:V2SI 0 "register_operand" "=y") - (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))] + [(set (match_operand:V2SI 0 "register_operand" "=v,?!y") + (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vBm,xm")))] "TARGET_SSE2" - "cvttpd2pi\t{%1, %0|%0, %1}" + "@ + * return TARGET_AVX ? \"vcvttpd2dq{x}\t{%1, %0|%0, %1}\" : \"cvttpd2dq\t{%1, %0|%0, %1}\"; + cvttpd2pi\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") - (set_attr "unit" "mmx") + (set_attr "unit" "*,mmx") + (set_attr "amdfam10_decode" "double") + (set_attr "athlon_decode" "vector") (set_attr "bdver1_decode" "double") - (set_attr "prefix_data16" "1") + (set_attr "prefix_data16" "*,1") + (set_attr "prefix" "maybe_vex,*") (set_attr "mode" "TI")]) (define_insn "sse2_cvtsi2sd" @@ -12854,13 +12866,15 @@ (vec_concat: (match_operand:VI8F_256 1 "register_operand" "v") (match_operand:VI8F_256 2 "nonimmediate_operand" "vm")) - (parallel [(match_operand 3 "const_0_to_3_operand") - (match_operand 4 "const_0_to_3_operand") - (match_operand 5 "const_4_to_7_operand") - (match_operand 6 "const_4_to_7_operand")])))] + (parallel [(match_operand 3 "const_0_to_3_operand") + (match_operand 4 "const_0_to_3_operand") + (match_operand 5 "const_4_to_7_operand") + (match_operand 6 "const_4_to_7_operand")])))] "TARGET_AVX512VL - && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1) - && INTVAL (operands[5]) == (INTVAL (operands[6]) - 1))" + && (INTVAL (operands[3]) & 1) == 0 + && INTVAL (operands[3]) == INTVAL (operands[4]) - 1 + && (INTVAL (operands[5]) & 1) == 0 + && INTVAL (operands[5]) == INTVAL (operands[6]) - 1" { int mask; mask = INTVAL (operands[3]) / 2; @@ -12903,19 +12917,23 @@ (vec_concat: (match_operand:V8FI 1 "register_operand" "v") (match_operand:V8FI 2 "nonimmediate_operand" "vm")) - (parallel [(match_operand 3 "const_0_to_7_operand") - (match_operand 4 "const_0_to_7_operand") - (match_operand 5 "const_0_to_7_operand") - (match_operand 6 "const_0_to_7_operand") - (match_operand 7 "const_8_to_15_operand") - (match_operand 8 "const_8_to_15_operand") - (match_operand 9 "const_8_to_15_operand") - (match_operand 10 "const_8_to_15_operand")])))] + (parallel [(match_operand 3 "const_0_to_7_operand") + (match_operand 4 "const_0_to_7_operand") + (match_operand 5 "const_0_to_7_operand") + (match_operand 6 "const_0_to_7_operand") + (match_operand 7 "const_8_to_15_operand") + (match_operand 8 "const_8_to_15_operand") + (match_operand 9 "const_8_to_15_operand") + (match_operand 10 "const_8_to_15_operand")])))] "TARGET_AVX512F - && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1) - && INTVAL (operands[5]) == (INTVAL (operands[6]) - 1) - && INTVAL (operands[7]) == (INTVAL (operands[8]) - 1) - && INTVAL (operands[9]) == (INTVAL (operands[10]) - 1))" + && (INTVAL (operands[3]) & 1) == 0 + && INTVAL (operands[3]) == INTVAL (operands[4]) - 1 + && (INTVAL (operands[5]) & 1) == 0 + && INTVAL (operands[5]) == INTVAL (operands[6]) - 1 + && (INTVAL (operands[7]) & 1) == 0 + && INTVAL (operands[7]) == INTVAL (operands[8]) - 1 + && (INTVAL (operands[9]) & 1) == 0 + && INTVAL (operands[9]) == INTVAL (operands[10]) - 1" { int mask; mask = INTVAL (operands[3]) / 2; @@ -12961,21 +12979,23 @@ (vec_concat: (match_operand:VI4F_256 1 "register_operand" "v") (match_operand:VI4F_256 2 "nonimmediate_operand" "vm")) - (parallel [(match_operand 3 "const_0_to_7_operand") - (match_operand 4 "const_0_to_7_operand") - (match_operand 5 "const_0_to_7_operand") - (match_operand 6 "const_0_to_7_operand") - (match_operand 7 "const_8_to_15_operand") - (match_operand 8 "const_8_to_15_operand") - (match_operand 9 "const_8_to_15_operand") + (parallel [(match_operand 3 "const_0_to_7_operand") + (match_operand 4 "const_0_to_7_operand") + (match_operand 5 "const_0_to_7_operand") + (match_operand 6 "const_0_to_7_operand") + (match_operand 7 "const_8_to_15_operand") + (match_operand 8 "const_8_to_15_operand") + (match_operand 9 "const_8_to_15_operand") (match_operand 10 "const_8_to_15_operand")])))] "TARGET_AVX512VL - && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1) - && INTVAL (operands[3]) == (INTVAL (operands[5]) - 2) - && INTVAL (operands[3]) == (INTVAL (operands[6]) - 3) - && INTVAL (operands[7]) == (INTVAL (operands[8]) - 1) - && INTVAL (operands[7]) == (INTVAL (operands[9]) - 2) - && INTVAL (operands[7]) == (INTVAL (operands[10]) - 3))" + && (INTVAL (operands[3]) & 3) == 0 + && INTVAL (operands[3]) == INTVAL (operands[4]) - 1 + && INTVAL (operands[3]) == INTVAL (operands[5]) - 2 + && INTVAL (operands[3]) == INTVAL (operands[6]) - 3 + && (INTVAL (operands[7]) & 3) == 0 + && INTVAL (operands[7]) == INTVAL (operands[8]) - 1 + && INTVAL (operands[7]) == INTVAL (operands[9]) - 2 + && INTVAL (operands[7]) == INTVAL (operands[10]) - 3" { int mask; mask = INTVAL (operands[3]) / 4; @@ -13027,35 +13047,39 @@ (vec_concat: (match_operand:V16FI 1 "register_operand" "v") (match_operand:V16FI 2 "nonimmediate_operand" "vm")) - (parallel [(match_operand 3 "const_0_to_15_operand") - (match_operand 4 "const_0_to_15_operand") - (match_operand 5 "const_0_to_15_operand") - (match_operand 6 "const_0_to_15_operand") - (match_operand 7 "const_0_to_15_operand") - (match_operand 8 "const_0_to_15_operand") - (match_operand 9 "const_0_to_15_operand") - (match_operand 10 "const_0_to_15_operand") - (match_operand 11 "const_16_to_31_operand") - (match_operand 12 "const_16_to_31_operand") - (match_operand 13 "const_16_to_31_operand") - (match_operand 14 "const_16_to_31_operand") - (match_operand 15 "const_16_to_31_operand") - (match_operand 16 "const_16_to_31_operand") - (match_operand 17 "const_16_to_31_operand") - (match_operand 18 "const_16_to_31_operand")])))] + (parallel [(match_operand 3 "const_0_to_15_operand") + (match_operand 4 "const_0_to_15_operand") + (match_operand 5 "const_0_to_15_operand") + (match_operand 6 "const_0_to_15_operand") + (match_operand 7 "const_0_to_15_operand") + (match_operand 8 "const_0_to_15_operand") + (match_operand 9 "const_0_to_15_operand") + (match_operand 10 "const_0_to_15_operand") + (match_operand 11 "const_16_to_31_operand") + (match_operand 12 "const_16_to_31_operand") + (match_operand 13 "const_16_to_31_operand") + (match_operand 14 "const_16_to_31_operand") + (match_operand 15 "const_16_to_31_operand") + (match_operand 16 "const_16_to_31_operand") + (match_operand 17 "const_16_to_31_operand") + (match_operand 18 "const_16_to_31_operand")])))] "TARGET_AVX512F - && (INTVAL (operands[3]) == (INTVAL (operands[4]) - 1) - && INTVAL (operands[3]) == (INTVAL (operands[5]) - 2) - && INTVAL (operands[3]) == (INTVAL (operands[6]) - 3) - && INTVAL (operands[7]) == (INTVAL (operands[8]) - 1) - && INTVAL (operands[7]) == (INTVAL (operands[9]) - 2) - && INTVAL (operands[7]) == (INTVAL (operands[10]) - 3) - && INTVAL (operands[11]) == (INTVAL (operands[12]) - 1) - && INTVAL (operands[11]) == (INTVAL (operands[13]) - 2) - && INTVAL (operands[11]) == (INTVAL (operands[14]) - 3) - && INTVAL (operands[15]) == (INTVAL (operands[16]) - 1) - && INTVAL (operands[15]) == (INTVAL (operands[17]) - 2) - && INTVAL (operands[15]) == (INTVAL (operands[18]) - 3))" + && (INTVAL (operands[3]) & 3) == 0 + && INTVAL (operands[3]) == INTVAL (operands[4]) - 1 + && INTVAL (operands[3]) == INTVAL (operands[5]) - 2 + && INTVAL (operands[3]) == INTVAL (operands[6]) - 3 + && (INTVAL (operands[7]) & 3) == 0 + && INTVAL (operands[7]) == INTVAL (operands[8]) - 1 + && INTVAL (operands[7]) == INTVAL (operands[9]) - 2 + && INTVAL (operands[7]) == INTVAL (operands[10]) - 3 + && (INTVAL (operands[11]) & 3) == 0 + && INTVAL (operands[11]) == INTVAL (operands[12]) - 1 + && INTVAL (operands[11]) == INTVAL (operands[13]) - 2 + && INTVAL (operands[11]) == INTVAL (operands[14]) - 3 + && (INTVAL (operands[15]) & 3) == 0 + && INTVAL (operands[15]) == INTVAL (operands[16]) - 1 + && INTVAL (operands[15]) == INTVAL (operands[17]) - 2 + && INTVAL (operands[15]) == INTVAL (operands[18]) - 3" { int mask; mask = INTVAL (operands[3]) / 4; @@ -16245,9 +16269,11 @@ switch (INTVAL (operands[4])) { case 3: - return "vgatherpf0ps\t{%5%{%0%}|%5%{%0%}}"; + /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as + gas changed what it requires incompatibly. */ + return "vgatherpf0ps\t{%5%{%0%}|%X5%{%0%}}"; case 2: - return "vgatherpf1ps\t{%5%{%0%}|%5%{%0%}}"; + return "vgatherpf1ps\t{%5%{%0%}|%X5%{%0%}}"; default: gcc_unreachable (); } @@ -16290,9 +16316,11 @@ switch (INTVAL (operands[4])) { case 3: - return "vgatherpf0pd\t{%5%{%0%}|%5%{%0%}}"; + /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as + gas changed what it requires incompatibly. */ + return "vgatherpf0pd\t{%5%{%0%}|%X5%{%0%}}"; case 2: - return "vgatherpf1pd\t{%5%{%0%}|%5%{%0%}}"; + return "vgatherpf1pd\t{%5%{%0%}|%X5%{%0%}}"; default: gcc_unreachable (); } @@ -16336,10 +16364,12 @@ { case 3: case 7: - return "vscatterpf0ps\t{%5%{%0%}|%5%{%0%}}"; + /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as + gas changed what it requires incompatibly. */ + return "vscatterpf0ps\t{%5%{%0%}|%X5%{%0%}}"; case 2: case 6: - return "vscatterpf1ps\t{%5%{%0%}|%5%{%0%}}"; + return "vscatterpf1ps\t{%5%{%0%}|%X5%{%0%}}"; default: gcc_unreachable (); } @@ -16383,10 +16413,12 @@ { case 3: case 7: - return "vscatterpf0pd\t{%5%{%0%}|%5%{%0%}}"; + /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as + gas changed what it requires incompatibly. */ + return "vscatterpf0pd\t{%5%{%0%}|%X5%{%0%}}"; case 2: case 6: - return "vscatterpf1pd\t{%5%{%0%}|%5%{%0%}}"; + return "vscatterpf1pd\t{%5%{%0%}|%X5%{%0%}}"; default: gcc_unreachable (); } @@ -17478,7 +17510,7 @@ for (regno = 0; regno < nregs; regno++) XVECEXP (operands[0], 0, regno + 1) - = gen_rtx_SET (gen_rtx_REG (V8SImode, SSE_REGNO (regno)), + = gen_rtx_SET (gen_rtx_REG (V8SImode, GET_SSE_REGNO (regno)), CONST0_RTX (V8SImode)); }) @@ -19261,12 +19293,6 @@ (set_attr "prefix" "vex") (set_attr "mode" "")]) -;; Memory operand override for -masm=intel of the v*gatherq* patterns. -(define_mode_attr gatherq_mode - [(V4SI "q") (V2DI "x") (V4SF "q") (V2DF "x") - (V8SI "x") (V4DI "t") (V8SF "x") (V4DF "t") - (V16SI "t") (V8DI "g") (V16SF "t") (V8DF "g")]) - (define_expand "_gathersi" [(parallel [(set (match_operand:VI48F 0 "register_operand") (unspec:VI48F @@ -19300,7 +19326,9 @@ UNSPEC_GATHER)) (clobber (match_scratch: 2 "=&Yk"))] "TARGET_AVX512F" - "vgatherd\t{%6, %0%{%2%}|%0%{%2%}, %6}" +;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as +;; gas changed what it requires incompatibly. + "vgatherd\t{%6, %0%{%2%}|%0%{%2%}, %X6}" [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -19319,7 +19347,9 @@ UNSPEC_GATHER)) (clobber (match_scratch: 1 "=&Yk"))] "TARGET_AVX512F" - "vgatherd\t{%5, %0%{%1%}|%0%{%1%}, %5}" +;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as +;; gas changed what it requires incompatibly. + "vgatherd\t{%5, %0%{%1%}|%0%{%1%}, %X5}" [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -19358,9 +19388,9 @@ UNSPEC_GATHER)) (clobber (match_scratch:QI 2 "=&Yk"))] "TARGET_AVX512F" -{ - return "vgatherq\t{%6, %1%{%2%}|%1%{%2%}, %6}"; -} +;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as +;; gas changed what it requires incompatibly. + "vgatherq\t{%6, %1%{%2%}|%1%{%2%}, %X6}" [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -19380,14 +19410,16 @@ (clobber (match_scratch:QI 1 "=&Yk"))] "TARGET_AVX512F" { + /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as + gas changed what it requires incompatibly. */ if (mode != mode) { if ( != 64) - return "vgatherq\t{%5, %x0%{%1%}|%x0%{%1%}, %5}"; + return "vgatherq\t{%5, %x0%{%1%}|%x0%{%1%}, %X5}"; else - return "vgatherq\t{%5, %t0%{%1%}|%t0%{%1%}, %t5}"; + return "vgatherq\t{%5, %t0%{%1%}|%t0%{%1%}, %X5}"; } - return "vgatherq\t{%5, %0%{%1%}|%0%{%1%}, %5}"; + return "vgatherq\t{%5, %0%{%1%}|%0%{%1%}, %X5}"; } [(set_attr "type" "ssemov") (set_attr "prefix" "evex") @@ -19424,7 +19456,9 @@ UNSPEC_SCATTER)) (clobber (match_scratch: 1 "=&Yk"))] "TARGET_AVX512F" - "vscatterd\t{%3, %5%{%1%}|%5%{%1%}, %3}" +;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as +;; gas changed what it requires incompatibly. + "vscatterd\t{%3, %5%{%1%}|%X5%{%1%}, %3}" [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "")]) @@ -19460,11 +19494,9 @@ UNSPEC_SCATTER)) (clobber (match_scratch:QI 1 "=&Yk"))] "TARGET_AVX512F" -{ - if (GET_MODE_SIZE (GET_MODE_INNER (mode)) == 8) - return "vscatterq\t{%3, %5%{%1%}|%5%{%1%}, %3}"; - return "vscatterq\t{%3, %5%{%1%}|%t5%{%1%}, %3}"; -} +;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as +;; gas changed what it requires incompatibly. + "vscatterq\t{%3, %5%{%1%}|%X5%{%1%}, %3}" [(set_attr "type" "ssemov") (set_attr "prefix" "evex") (set_attr "mode" "")]) diff --git a/contrib/gcc-8.0/gcc/config/i386/vpclmulqdqintrin.h b/contrib/gcc-8.0/gcc/config/i386/vpclmulqdqintrin.h index c70c5039b5..3fafa425dc 100644 --- a/contrib/gcc-8.0/gcc/config/i386/vpclmulqdqintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/vpclmulqdqintrin.h @@ -78,9 +78,9 @@ _mm_clmulepi64_epi128 (__m128i __A, __m128i __B, const int __C) #pragma GCC pop_options #endif /* __DISABLE_VPCLMULQDQVL__ */ -#if !defined(__VPCLMULQDQ__) || !defined(__AVX512VL__) +#if !defined(__VPCLMULQDQ__) || !defined(__AVX__) #pragma GCC push_options -#pragma GCC target("vpclmulqdq,avx512vl") +#pragma GCC target("vpclmulqdq,avx") #define __DISABLE_VPCLMULQDQ__ #endif /* __VPCLMULQDQ__ */ @@ -103,6 +103,4 @@ _mm256_clmulepi64_epi128 (__m256i __A, __m256i __B, const int __C) #pragma GCC pop_options #endif /* __DISABLE_VPCLMULQDQ__ */ - #endif /* _VPCLMULQDQINTRIN_H_INCLUDED */ - diff --git a/contrib/gcc-8.0/gcc/config/i386/x86-tune.def b/contrib/gcc-8.0/gcc/config/i386/x86-tune.def index 5649fdcf41..c99e45cba5 100644 --- a/contrib/gcc-8.0/gcc/config/i386/x86-tune.def +++ b/contrib/gcc-8.0/gcc/config/i386/x86-tune.def @@ -48,9 +48,9 @@ DEF_TUNE (X86_TUNE_SCHEDULE, "schedule", over partial stores. For example preffer MOVZBL or MOVQ to load 8bit value over movb. */ DEF_TUNE (X86_TUNE_PARTIAL_REG_DEPENDENCY, "partial_reg_dependency", - m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE + m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_BONNELL | m_SILVERMONT | m_INTEL - | m_KNL | m_KNM | m_AMD_MULTIPLE | m_SKYLAKE_AVX512 | m_GENERIC) + | m_KNL | m_KNM | m_AMD_MULTIPLE | m_GENERIC) /* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: This knob promotes all store destinations to be 128bit to allow register renaming on 128bit SSE units, @@ -84,8 +84,8 @@ DEF_TUNE (X86_TUNE_PARTIAL_FLAG_REG_STALL, "partial_flag_reg_stall", partial dependencies. */ DEF_TUNE (X86_TUNE_MOVX, "movx", m_PPRO | m_P4_NOCONA | m_CORE2 | m_NEHALEM | m_SANDYBRIDGE - | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL - | m_GEODE | m_AMD_MULTIPLE | m_SKYLAKE_AVX512 | m_GENERIC) + | m_BONNELL | m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_CORE_AVX2 + | m_GEODE | m_AMD_MULTIPLE | m_GENERIC) /* X86_TUNE_MEMORY_MISMATCH_STALL: Avoid partial stores that are followed by full sized loads. */ @@ -101,19 +101,19 @@ DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_32, "fuse_cmp_and_branch_32", /* X86_TUNE_FUSE_CMP_AND_BRANCH_64: Fuse compare with a subsequent conditional jump instruction for TARGET_64BIT. */ DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_64, "fuse_cmp_and_branch_64", - m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_BDVER | m_ZNVER1 | m_GENERIC) + m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_BDVER | m_ZNVER1 | m_GENERIC) /* X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS: Fuse compare with a subsequent conditional jump instruction when the condition jump check sign flag (SF) or overflow flag (OF). */ DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS, "fuse_cmp_and_branch_soflags", - m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_BDVER | m_ZNVER1 | m_GENERIC) + m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_BDVER | m_ZNVER1 | m_GENERIC) /* X86_TUNE_FUSE_ALU_AND_BRANCH: Fuse alu with a subsequent conditional jump instruction when the alu instruction produces the CCFLAG consumed by the conditional jump instruction. */ DEF_TUNE (X86_TUNE_FUSE_ALU_AND_BRANCH, "fuse_alu_and_branch", - m_SANDYBRIDGE | m_HASWELL | m_GENERIC) + m_SANDYBRIDGE | m_CORE_AVX2 | m_GENERIC) /*****************************************************************************/ @@ -286,7 +286,7 @@ DEF_TUNE (X86_TUNE_USE_BT, "use_bt", /* X86_TUNE_AVOID_FALSE_DEP_FOR_BMI: Avoid false dependency for bit-manipulation instructions. */ DEF_TUNE (X86_TUNE_AVOID_FALSE_DEP_FOR_BMI, "avoid_false_dep_for_bmi", - m_SANDYBRIDGE | m_HASWELL | m_GENERIC) + m_SANDYBRIDGE | m_CORE_AVX2 | m_GENERIC) /* X86_TUNE_ADJUST_UNROLL: This enables adjusting the unroll factor based on hardware capabilities. Bdver3 hardware has a loop buffer which makes @@ -335,15 +335,15 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill", /* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL: Use movups for misaligned loads instead of a sequence loading registers by parts. */ DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal", - m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_SILVERMONT | m_KNL | m_KNM - | m_INTEL | m_SKYLAKE_AVX512 | m_AMDFAM10 | m_BDVER | m_BTVER + m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM + | m_INTEL | m_AMDFAM10 | m_BDVER | m_BTVER | m_ZNVER1 | m_GENERIC) /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL: Use movups for misaligned stores instead of a sequence loading registers by parts. */ DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal", - m_NEHALEM | m_SANDYBRIDGE | m_HASWELL | m_SILVERMONT | m_KNL | m_KNM - | m_INTEL | m_SKYLAKE_AVX512 | m_BDVER | m_ZNVER1 | m_GENERIC) + m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2 | m_SILVERMONT | m_KNL | m_KNM + | m_INTEL | m_BDVER | m_ZNVER1 | m_GENERIC) /* Use packed single precision instructions where posisble. I.e. movups instead of movupd. */ @@ -429,7 +429,7 @@ DEF_TUNE (X86_TUNE_AVX128_OPTIMAL, "avx128_optimal", m_BDVER | m_BTVER2 /* X86_TUNE_AVX256_OPTIMAL: Use 256-bit AVX instructions instead of 512-bit AVX instructions in the auto-vectorizer. */ -DEF_TUNE (X86_TUNE_AVX256_OPTIMAL, "avx256_optimal", m_SKYLAKE_AVX512) +DEF_TUNE (X86_TUNE_AVX256_OPTIMAL, "avx256_optimal", m_CORE_AVX512) /*****************************************************************************/ /* Historical relics: tuning flags that helps a specific old CPU designs */ diff --git a/contrib/gcc-8.0/gcc/config/i386/xsaveintrin.h b/contrib/gcc-8.0/gcc/config/i386/xsaveintrin.h index 705936e91b..3f6c80b9ba 100644 --- a/contrib/gcc-8.0/gcc/config/i386/xsaveintrin.h +++ b/contrib/gcc-8.0/gcc/config/i386/xsaveintrin.h @@ -59,7 +59,7 @@ extern __inline long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _xgetbv (unsigned int __A) { - __builtin_ia32_xgetbv (__A); + return __builtin_ia32_xgetbv (__A); } #ifdef __x86_64__ diff --git a/contrib/gcc-8.0/gcc/coverage.c b/contrib/gcc-8.0/gcc/coverage.c index 32ef298a11..592d3dcef8 100644 --- a/contrib/gcc-8.0/gcc/coverage.c +++ b/contrib/gcc-8.0/gcc/coverage.c @@ -368,7 +368,7 @@ get_coverage_counts (unsigned counter, unsigned expected, else { gcc_assert (coverage_node_map_initialized_p ()); - elt.ident = cgraph_node::get (cfun->decl)->profile_id; + elt.ident = cgraph_node::get (current_function_decl)->profile_id; } elt.ctr = counter; entry = counts_hash->find (&elt); @@ -663,7 +663,8 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum) gcov_write_unsigned (cfg_checksum); gcov_write_string (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); - gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)); + gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl) + && !DECL_LAMBDA_FUNCTION (current_function_decl)); gcov_write_filename (xloc.file); gcov_write_unsigned (xloc.line); gcov_write_unsigned (xloc.column); @@ -671,7 +672,11 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum) expanded_location endloc = expand_location (cfun->function_end_locus); /* Function can start in a single file and end in another one. */ - gcov_write_unsigned (endloc.file == xloc.file ? endloc.line : xloc.line); + /* Work-around for PR gcov-profile/88045. */ + int end_line = endloc.file == xloc.file ? endloc.line : xloc.line; + if (xloc.line > end_line) + end_line = xloc.line; + gcov_write_unsigned (end_line); gcov_write_length (offset); return !gcov_is_error (); diff --git a/contrib/gcc-8.0/gcc/cp/call.c b/contrib/gcc-8.0/gcc/cp/call.c index fb6d71d260..f16f289540 100644 --- a/contrib/gcc-8.0/gcc/cp/call.c +++ b/contrib/gcc-8.0/gcc/cp/call.c @@ -1396,6 +1396,13 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL))) || SCOPED_ENUM_P (from)) return NULL; + + /* If we're parsing an enum with no fixed underlying type, we're + dealing with an incomplete type, which renders the conversion + ill-formed. */ + if (!COMPLETE_TYPE_P (from)) + return NULL; + conv = build_conv (ck_std, to, conv); /* Give this a better rank if it's a promotion. */ @@ -6783,7 +6790,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, return expr; } - expr = mark_rvalue_use (expr); + /* We don't know here whether EXPR is being used as an lvalue or + rvalue, but we know it's read. */ + mark_exp_read (expr); /* Pass LOOKUP_NO_CONVERSION so rvalue/base handling knows not to allow any more UDCs. */ @@ -6872,7 +6881,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, elttype = cp_build_qualified_type (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST); array = build_array_of_n_type (elttype, len); - array = finish_compound_literal (array, new_ctor, complain); + array = finish_compound_literal (array, new_ctor, complain, fcl_c99); /* Take the address explicitly rather than via decay_conversion to avoid the error about taking the address of a temporary. */ array = cp_build_addr_expr (array, complain); @@ -10824,14 +10833,12 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type) tree name = mangle_ref_init_variable (decl); DECL_NAME (var) = name; SET_DECL_ASSEMBLER_NAME (var, name); - - var = pushdecl (var); } else /* Create a new cleanup level if necessary. */ maybe_push_cleanup_level (type); - return var; + return pushdecl (var); } /* EXPR is the initializer for a variable DECL of reference or @@ -11035,7 +11042,9 @@ extend_ref_init_temps_1 (tree decl, tree init, vec **cleanups) if (TREE_CODE (sub) != ADDR_EXPR) return init; /* Deal with binding to a subobject. */ - for (p = &TREE_OPERAND (sub, 0); TREE_CODE (*p) == COMPONENT_REF; ) + for (p = &TREE_OPERAND (sub, 0); + (TREE_CODE (*p) == COMPONENT_REF + || TREE_CODE (*p) == ARRAY_REF); ) p = &TREE_OPERAND (*p, 0); if (TREE_CODE (*p) == TARGET_EXPR) { diff --git a/contrib/gcc-8.0/gcc/cp/class.c b/contrib/gcc-8.0/gcc/cp/class.c index 0427d1224f..834ba17a85 100644 --- a/contrib/gcc-8.0/gcc/cp/class.c +++ b/contrib/gcc-8.0/gcc/cp/class.c @@ -278,6 +278,9 @@ build_base_path (enum tree_code code, probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr)); if (want_pointer) probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe)); + if (dependent_type_p (probe)) + if (tree open = currently_open_class (probe)) + probe = open; if (code == PLUS_EXPR && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe)) @@ -417,7 +420,7 @@ build_base_path (enum tree_code code, { expr = cp_build_fold_indirect_ref (expr); expr = build_simple_base_path (expr, binfo); - if (rvalue) + if (rvalue && lvalue_p (expr)) expr = move (expr); if (want_pointer) expr = build_address (expr); @@ -1138,9 +1141,6 @@ add_method (tree type, tree method, bool via_using) } } - /* A class should never have more than one destructor. */ - gcc_assert (!current_fns || !DECL_DESTRUCTOR_P (method)); - current_fns = ovl_insert (method, current_fns, via_using); if (!COMPLETE_TYPE_P (type) && !DECL_CONV_FN_P (method) @@ -1954,6 +1954,7 @@ fixup_attribute_variants (tree t) unsigned align = TYPE_ALIGN (t); bool user_align = TYPE_USER_ALIGN (t); bool may_alias = lookup_attribute ("may_alias", attrs); + bool packed = TYPE_PACKED (t); if (may_alias) fixup_may_alias (t); @@ -1971,6 +1972,7 @@ fixup_attribute_variants (tree t) else TYPE_USER_ALIGN (variants) = user_align; SET_TYPE_ALIGN (variants, valign); + TYPE_PACKED (variants) = packed; if (may_alias) fixup_may_alias (variants); } @@ -2025,6 +2027,7 @@ maybe_warn_about_overly_private_class (tree t) { int has_member_fn = 0; int has_nonprivate_method = 0; + bool nonprivate_ctor = false; if (!warn_ctor_dtor_privacy /* If the class has friends, those entities might create and @@ -2055,7 +2058,11 @@ maybe_warn_about_overly_private_class (tree t) non-private statics, we can't ever call any of the private member functions.) */ for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn)) - if (!DECL_DECLARES_FUNCTION_P (fn)) + if (TREE_CODE (fn) == USING_DECL + && DECL_NAME (fn) == ctor_identifier + && !TREE_PRIVATE (fn)) + nonprivate_ctor = true; + else if (!DECL_DECLARES_FUNCTION_P (fn)) /* Not a function. */; else if (DECL_ARTIFICIAL (fn)) /* We're not interested in compiler-generated methods; they don't @@ -2117,7 +2124,6 @@ maybe_warn_about_overly_private_class (tree t) /* Implicitly generated constructors are always public. */ && !CLASSTYPE_LAZY_DEFAULT_CTOR (t)) { - bool nonprivate_ctor = false; tree copy_or_move = NULL_TREE; /* If a non-template class does not define a copy @@ -5171,6 +5177,19 @@ classtype_has_move_assign_or_move_ctor_p (tree t, bool user_p) return false; } +/* True iff T has a move constructor that is not deleted. */ + +bool +classtype_has_non_deleted_move_ctor (tree t) +{ + if (CLASSTYPE_LAZY_MOVE_CTOR (t)) + lazily_declare_fn (sfk_move_constructor, t); + for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) + if (move_fn_p (*iter) && !DECL_DELETED_FN (*iter)) + return true; + return false; +} + /* Nonzero if we need to build up a constructor call when initializing an object of this class, either because it has a user-declared constructor or because it doesn't have a default constructor (so we need to give an @@ -6226,6 +6245,7 @@ layout_class_type (tree t, tree *virtuals_p) bitsize_int (BITS_PER_UNIT))); SET_TYPE_ALIGN (base_t, rli->record_align); TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t); + TYPE_TYPELESS_STORAGE (base_t) = TYPE_TYPELESS_STORAGE (t); /* Copy the non-static data members of T. This will include its direct non-virtual bases & vtable. */ @@ -7014,6 +7034,20 @@ finish_struct (tree t, tree attributes) else if (DECL_DECLARES_FUNCTION_P (x)) DECL_IN_AGGR_P (x) = false; + /* Also add a USING_DECL for operator=. We know there'll be (at + least) one, but we don't know the signature(s). We want name + lookup not to fail or recurse into bases. This isn't added + to the template decl list so we drop this at instantiation + time. */ + tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier, + NULL_TREE); + DECL_CONTEXT (ass_op) = t; + USING_DECL_SCOPE (ass_op) = t; + DECL_DEPENDENT_P (ass_op) = true; + DECL_ARTIFICIAL (ass_op) = true; + DECL_CHAIN (ass_op) = TYPE_FIELDS (t); + TYPE_FIELDS (t) = ass_op; + TYPE_SIZE (t) = bitsize_zero_node; TYPE_SIZE_UNIT (t) = size_zero_node; /* COMPLETE_TYPE_P is now true. */ @@ -7427,8 +7461,8 @@ pop_class_stack (void) --current_class_stack[current_class_depth - 1].hidden; } -/* Returns 1 if the class type currently being defined is either T or - a nested type of T. Returns the type from the current_class_stack, +/* If the class type currently being defined is either T or + a nested type of T, returns the type from the current_class_stack, which might be equivalent to but not equal to T in case of constrained partial specializations. */ diff --git a/contrib/gcc-8.0/gcc/cp/constexpr.c b/contrib/gcc-8.0/gcc/cp/constexpr.c index b4bcc6a567..f161984e20 100644 --- a/contrib/gcc-8.0/gcc/cp/constexpr.c +++ b/contrib/gcc-8.0/gcc/cp/constexpr.c @@ -1252,6 +1252,8 @@ adjust_temp_type (tree type, tree temp) /* Avoid wrapping an aggregate value in a NOP_EXPR. */ if (TREE_CODE (temp) == CONSTRUCTOR) return build_constructor (type, CONSTRUCTOR_ELTS (temp)); + if (TREE_CODE (temp) == EMPTY_CLASS_EXPR) + return build0 (EMPTY_CLASS_EXPR, type); gcc_assert (scalarish_type_p (type)); return cp_fold_convert (type, temp); } @@ -2066,6 +2068,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t, { if (!ctx->quiet) error ("arithmetic involving a null pointer in %qE", lhs); + *non_constant_p = true; return t; } else if (code == POINTER_PLUS_EXPR) @@ -2506,9 +2509,13 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, lval, non_constant_p, overflow_p); if (INDIRECT_REF_P (whole) - && integer_zerop (TREE_OPERAND (whole, 0)) - && !ctx->quiet) - error ("dereferencing a null pointer in %qE", orig_whole); + && integer_zerop (TREE_OPERAND (whole, 0))) + { + if (!ctx->quiet) + error ("dereferencing a null pointer in %qE", orig_whole); + *non_constant_p = true; + return t; + } if (TREE_CODE (whole) == PTRMEM_CST) whole = cplus_expand_constant (whole); @@ -2989,6 +2996,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, { /* Initializing an element using value or default initialization we just pre-built above. */ + if (init == void_node) + /* Trivial default-init, don't do anything to the CONSTRUCTOR. */ + return ctx->ctor; eltinit = cxx_eval_constant_expression (&new_ctx, init, lval, non_constant_p, overflow_p); reuse = i == 0; @@ -3926,6 +3936,16 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t, for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) { tree stmt = tsi_stmt (i); + /* We've found a continue, so skip everything until we reach + the label its jumping to. */ + if (continues (jump_target)) + { + if (label_matches (ctx, jump_target, stmt)) + /* Found it. */ + *jump_target = NULL_TREE; + else + continue; + } if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT) continue; r = cxx_eval_constant_expression (ctx, stmt, false, @@ -3993,13 +4013,13 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t, bool *non_constant_p, bool *overflow_p, tree *jump_target) { - tree cond = TREE_OPERAND (t, 0); + tree cond = SWITCH_COND (t); cond = cxx_eval_constant_expression (ctx, cond, false, non_constant_p, overflow_p); VERIFY_CONSTANT (cond); *jump_target = cond; - tree body = TREE_OPERAND (t, 1); + tree body = SWITCH_BODY (t); constexpr_ctx new_ctx = *ctx; constexpr_switch_state css = css_default_not_seen; new_ctx.css_state = &css; @@ -4528,6 +4548,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case COND_EXPR: if (jump_target && *jump_target) { + tree orig_jump = *jump_target; /* When jumping to a label, the label might be either in the then or else blocks, so process then block first in skipping mode first, and if we are still in the skipping mode at its end, @@ -4535,7 +4556,19 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), lval, non_constant_p, overflow_p, jump_target); - if (*jump_target) + /* It's possible that we found the label in the then block. But + it could have been followed by another jumping statement, e.g. + say we're looking for case 1: + if (cond) + { + // skipped statements + case 1:; // clears up *jump_target + return 1; // and sets it to a RETURN_EXPR + } + else { ... } + in which case we need not go looking to the else block. + (goto is not allowed in a constexpr function.) */ + if (*jump_target == orig_jump) r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2), lval, non_constant_p, overflow_p, jump_target); @@ -4551,7 +4584,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; case CONSTRUCTOR: - if (TREE_CONSTANT (t)) + if (TREE_CONSTANT (t) && reduced_constant_expression_p (t)) { /* Don't re-process a constant CONSTRUCTOR, but do fold it to VECTOR_CST if applicable. */ @@ -5107,12 +5140,12 @@ clear_cv_and_fold_caches (void) /* Like maybe_constant_value but first fully instantiate the argument. Note: this is equivalent to instantiate_non_dependent_expr_sfinae - (t, tf_none) followed by maybe_constant_value but is more efficient, + (t, complain) followed by maybe_constant_value but is more efficient, because calls instantiation_dependent_expression_p and potential_constant_expression at most once. */ tree -fold_non_dependent_expr (tree t) +fold_non_dependent_expr (tree t, tsubst_flags_t complain /* = tf_none */) { if (t == NULL_TREE) return NULL_TREE; @@ -5129,7 +5162,7 @@ fold_non_dependent_expr (tree t) if (is_nondependent_constant_expression (t)) { processing_template_decl_sentinel s; - t = instantiate_non_dependent_expr_internal (t, tf_none); + t = instantiate_non_dependent_expr_internal (t, complain); if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t)) diff --git a/contrib/gcc-8.0/gcc/cp/cp-gimplify.c b/contrib/gcc-8.0/gcc/cp/cp-gimplify.c index 7449065463..93bf3c3314 100644 --- a/contrib/gcc-8.0/gcc/cp/cp-gimplify.c +++ b/contrib/gcc-8.0/gcc/cp/cp-gimplify.c @@ -1085,6 +1085,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) if (h) { *stmt_p = h->to; + TREE_USED (h->to) |= TREE_USED (stmt); *walk_subtrees = 0; return NULL; } @@ -1463,6 +1464,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) case OMP_FOR: case OMP_SIMD: case OMP_DISTRIBUTE: + case OACC_LOOP: genericize_omp_for_stmt (stmt_p, walk_subtrees, data); break; @@ -1621,6 +1623,13 @@ cp_maybe_instrument_return (tree fndecl) case STATEMENT_LIST: { tree_stmt_iterator i = tsi_last (t); + while (!tsi_end_p (i)) + { + tree p = tsi_stmt (i); + if (TREE_CODE (p) != DEBUG_BEGIN_STMT) + break; + tsi_prev (&i); + } if (!tsi_end_p (i)) { t = tsi_stmt (i); @@ -1957,7 +1966,7 @@ cxx_omp_const_qual_no_mutable (tree decl) /* True if OpenMP sharing attribute of DECL is predetermined. */ enum omp_clause_default_kind -cxx_omp_predetermined_sharing (tree decl) +cxx_omp_predetermined_sharing_1 (tree decl) { /* Static data members are predetermined shared. */ if (TREE_STATIC (decl)) @@ -1975,6 +1984,32 @@ cxx_omp_predetermined_sharing (tree decl) return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } +/* Likewise, but also include the artificial vars. We don't want to + disallow the artificial vars being mentioned in explicit clauses, + as we use artificial vars e.g. for loop constructs with random + access iterators other than pointers, but during gimplification + we want to treat them as predetermined. */ + +enum omp_clause_default_kind +cxx_omp_predetermined_sharing (tree decl) +{ + enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl); + if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED) + return ret; + + /* Predetermine artificial variables holding integral values, those + are usually result of gimplify_one_sizepos or SAVE_EXPR + gimplification. */ + if (VAR_P (decl) + && DECL_ARTIFICIAL (decl) + && INTEGRAL_TYPE_P (TREE_TYPE (decl)) + && !(DECL_LANG_SPECIFIC (decl) + && DECL_OMP_PRIVATIZED_MEMBER (decl))) + return OMP_CLAUSE_DEFAULT_SHARED; + + return OMP_CLAUSE_DEFAULT_UNSPECIFIED; +} + /* Finalize an implicitly determined clause. */ void @@ -2231,8 +2266,9 @@ cp_fold (tree x) { val = TREE_OPERAND (val, 0); STRIP_NOPS (val); + val = maybe_constant_value (val); if (TREE_CODE (val) == INTEGER_CST) - return fold_convert (TREE_TYPE (x), fold_offsetof_1 (op0)); + return fold_offsetof (op0, TREE_TYPE (x)); } } goto finish_unary; diff --git a/contrib/gcc-8.0/gcc/cp/cp-tree.h b/contrib/gcc-8.0/gcc/cp/cp-tree.h index 72e4080b83..0f24b4fc94 100644 --- a/contrib/gcc-8.0/gcc/cp/cp-tree.h +++ b/contrib/gcc-8.0/gcc/cp/cp-tree.h @@ -6180,6 +6180,7 @@ extern bool trivial_default_constructor_is_constexpr (tree); extern bool type_has_constexpr_default_constructor (tree); extern bool type_has_virtual_destructor (tree); extern bool classtype_has_move_assign_or_move_ctor_p (tree, bool user_declared); +extern bool classtype_has_non_deleted_move_ctor (tree); extern bool type_build_ctor_call (tree); extern bool type_build_dtor_call (tree); extern void explain_non_literal_class (tree); @@ -6644,7 +6645,7 @@ extern bool template_parameter_pack_p (const_tree); extern bool function_parameter_pack_p (const_tree); extern bool function_parameter_expanded_from_pack_p (tree, tree); extern tree make_pack_expansion (tree, tsubst_flags_t = tf_warning_or_error); -extern bool check_for_bare_parameter_packs (tree); +extern bool check_for_bare_parameter_packs (tree, location_t = UNKNOWN_LOCATION); extern tree build_template_info (tree, tree); extern tree get_template_info (const_tree); extern vec *get_types_needing_access_check (tree); @@ -6827,9 +6828,9 @@ extern bool perform_or_defer_access_check (tree, tree, tree, struct deferring_access_check_sentinel { - deferring_access_check_sentinel () + deferring_access_check_sentinel (enum deferring_kind kind = dk_deferred) { - push_deferring_access_checks (dk_deferred); + push_deferring_access_checks (kind); } ~deferring_access_check_sentinel () { @@ -6896,7 +6897,7 @@ extern tree begin_compound_stmt (unsigned int); extern void finish_compound_stmt (tree); extern tree finish_asm_stmt (int, tree, tree, tree, tree, - tree); + tree, bool); extern tree finish_label_stmt (tree); extern void finish_label_decl (tree); extern cp_expr finish_parenthesized_expr (cp_expr); @@ -7035,6 +7036,7 @@ extern tree finish_builtin_launder (location_t, tree, tsubst_flags_t); extern void start_lambda_scope (tree); extern void record_lambda_scope (tree); +extern void record_null_lambda_scope (tree); extern void finish_lambda_scope (void); extern tree start_lambda_function (tree fn, tree lambda_expr); extern void finish_lambda_function (tree body); @@ -7096,6 +7098,7 @@ extern tree get_target_expr_sfinae (tree, tsubst_flags_t); extern tree build_cplus_array_type (tree, tree); extern tree build_array_of_n_type (tree, int); extern bool array_of_runtime_bound_p (tree); +extern bool vla_type_p (tree); extern tree build_array_copy (tree); extern tree build_vec_init_expr (tree, tree, tsubst_flags_t); extern void diagnose_non_constexpr_vec_init (tree); @@ -7409,6 +7412,7 @@ extern int cp_gimplify_expr (tree *, gimple_seq *, gimple_seq *); extern void cp_genericize (tree); extern bool cxx_omp_const_qual_no_mutable (tree); +extern enum omp_clause_default_kind cxx_omp_predetermined_sharing_1 (tree); extern enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree); extern tree cxx_omp_clause_default_ctor (tree, tree, tree); extern tree cxx_omp_clause_copy_ctor (tree, tree, tree); @@ -7542,7 +7546,7 @@ extern tree cxx_constant_value (tree, tree = NULL_TREE); extern tree cxx_constant_init (tree, tree = NULL_TREE); extern tree maybe_constant_value (tree, tree = NULL_TREE); extern tree maybe_constant_init (tree, tree = NULL_TREE); -extern tree fold_non_dependent_expr (tree); +extern tree fold_non_dependent_expr (tree, tsubst_flags_t = tf_none); extern tree fold_simple (tree); extern bool is_sub_constant_expr (tree); extern bool reduced_constant_expression_p (tree); diff --git a/contrib/gcc-8.0/gcc/cp/cvt.c b/contrib/gcc-8.0/gcc/cp/cvt.c index 0f045e2ab1..d0059a3276 100644 --- a/contrib/gcc-8.0/gcc/cp/cvt.c +++ b/contrib/gcc-8.0/gcc/cp/cvt.c @@ -1938,7 +1938,8 @@ can_convert_qual (tree type, tree expr) /* Attempt to perform qualification conversions on EXPR to convert it to TYPE. Return the resulting expression, or error_mark_node if - the conversion was impossible. */ + the conversion was impossible. Since this is only used by + convert_nontype_argument, we fold the conversion. */ tree perform_qualification_conversions (tree type, tree expr) @@ -1950,7 +1951,7 @@ perform_qualification_conversions (tree type, tree expr) if (same_type_p (type, expr_type)) return expr; else if (can_convert_qual (type, expr)) - return build_nop (type, expr); + return cp_fold_convert (type, expr); else return error_mark_node; } diff --git a/contrib/gcc-8.0/gcc/cp/decl.c b/contrib/gcc-8.0/gcc/cp/decl.c index 55e234334a..f6af3f9f57 100644 --- a/contrib/gcc-8.0/gcc/cp/decl.c +++ b/contrib/gcc-8.0/gcc/cp/decl.c @@ -6134,20 +6134,29 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, { if (TREE_CODE (init) == CONSTRUCTOR) { - if (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init))) - /* There is no need to reshape pointer-to-member function - initializers, as they are always constructed correctly - by the front end. */ - ; - else if (COMPOUND_LITERAL_P (init)) + tree init_type = TREE_TYPE (init); + if (init_type && TYPE_PTRMEMFUNC_P (init_type)) + /* There is no need to call reshape_init for pointer-to-member + function initializers, as they are always constructed correctly + by the front end. Here we have e.g. {.__pfn=0B, .__delta=0}, + which is missing outermost braces. We should warn below, and + one of the routines below will wrap it in additional { }. */; /* For a nested compound literal, there is no need to reshape since - brace elision is not allowed. Even if we decided to allow it, - we should add a call to reshape_init in finish_compound_literal, - before calling digest_init, so changing this code would still - not be necessary. */ - gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init)); + we called reshape_init in finish_compound_literal, before calling + digest_init. */ + else if (COMPOUND_LITERAL_P (init) + /* Similarly, a CONSTRUCTOR of the target's type is a + previously digested initializer. */ + || same_type_ignoring_top_level_qualifiers_p (type, + init_type)) + { + ++d->cur; + gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init)); + return init; + } else { + /* Something that hasn't been reshaped yet. */ ++d->cur; gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init)); return reshape_init (type, init, complain); @@ -7305,6 +7314,27 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (was_readonly) TREE_READONLY (decl) = 1; + if (flag_openmp + && VAR_P (decl) + && lookup_attribute ("omp declare target implicit", + DECL_ATTRIBUTES (decl))) + { + DECL_ATTRIBUTES (decl) + = remove_attribute ("omp declare target implicit", + DECL_ATTRIBUTES (decl)); + complete_type (TREE_TYPE (decl)); + if (!cp_omp_mappable_type (TREE_TYPE (decl))) + error ("%q+D in declare target directive does not have mappable type", + decl); + else if (!lookup_attribute ("omp declare target", + DECL_ATTRIBUTES (decl)) + && !lookup_attribute ("omp declare target link", + DECL_ATTRIBUTES (decl))) + DECL_ATTRIBUTES (decl) + = tree_cons (get_identifier ("omp declare target"), + NULL_TREE, DECL_ATTRIBUTES (decl)); + } + invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); } @@ -10255,6 +10285,9 @@ grokdeclarator (const cp_declarator *declarator, break; if (qualifying_scope) { + if (check_for_bare_parameter_packs (qualifying_scope, + id_declarator->id_loc)) + return error_mark_node; if (at_function_scope_p ()) { /* [dcl.meaning] @@ -15533,6 +15566,18 @@ begin_destructor_body (void) tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR, vtbl, tf_warning_or_error); + /* If the vptr is shared with some virtual nearly empty base, + don't clear it if not in charge, the dtor of the virtual + nearly empty base will do that later. */ + if (CLASSTYPE_VBASECLASSES (current_class_type) + && CLASSTYPE_PRIMARY_BINFO (current_class_type) + && BINFO_VIRTUAL_P + (CLASSTYPE_PRIMARY_BINFO (current_class_type))) + { + stmt = convert_to_void (stmt, ICV_STATEMENT, + tf_warning_or_error); + stmt = build_if_in_charge (stmt); + } finish_decl_cleanup (NULL_TREE, stmt); } else diff --git a/contrib/gcc-8.0/gcc/cp/decl2.c b/contrib/gcc-8.0/gcc/cp/decl2.c index b0bf8241f7..6a67c4e5b3 100644 --- a/contrib/gcc-8.0/gcc/cp/decl2.c +++ b/contrib/gcc-8.0/gcc/cp/decl2.c @@ -1514,11 +1514,11 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) && DECL_CLASS_SCOPE_P (*decl)) error ("%q+D static data member inside of declare target directive", *decl); - else if (!processing_template_decl - && VAR_P (*decl) - && !cp_omp_mappable_type (TREE_TYPE (*decl))) - error ("%q+D in declare target directive does not have mappable type", - *decl); + else if (VAR_P (*decl) + && (processing_template_decl + || !cp_omp_mappable_type (TREE_TYPE (*decl)))) + attributes = tree_cons (get_identifier ("omp declare target implicit"), + NULL_TREE, attributes); else attributes = tree_cons (get_identifier ("omp declare target"), NULL_TREE, attributes); @@ -1939,10 +1939,13 @@ vague_linkage_p (tree decl) { if (!TREE_PUBLIC (decl)) { - /* maybe_thunk_body clears TREE_PUBLIC on the maybe-in-charge 'tor - variants, check one of the "clones" for the real linkage. */ + /* maybe_thunk_body clears TREE_PUBLIC and DECL_ABSTRACT_P on the + maybe-in-charge 'tor variants; in that case we need to check one of + the "clones" for the real linkage. But only in that case; before + maybe_clone_body we haven't yet copied the linkage to the clones. */ if ((DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl) || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)) + && !DECL_ABSTRACT_P (decl) && DECL_CHAIN (decl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (decl))) return vague_linkage_p (DECL_CHAIN (decl)); @@ -2422,21 +2425,8 @@ determine_visibility (tree decl) } /* Local classes in templates have CLASSTYPE_USE_TEMPLATE set, - but have no TEMPLATE_INFO. Their containing template - function does, and the local class could be constrained - by that. */ - if (DECL_LANG_SPECIFIC (fn) && DECL_USE_TEMPLATE (fn)) - template_decl = fn; - else if (template_decl) - { - /* FN must be a regenerated lambda function, since they don't - have template arguments. Find a containing non-lambda - template instantiation. */ - tree ctx = fn; - while (ctx && !get_template_info (ctx)) - ctx = get_containing_scope (ctx); - template_decl = ctx; - } + but have no TEMPLATE_INFO, so don't try to check it. */ + template_decl = NULL_TREE; } else if (VAR_P (decl) && DECL_TINFO_P (decl) && flag_visibility_ms_compat) diff --git a/contrib/gcc-8.0/gcc/cp/error.c b/contrib/gcc-8.0/gcc/cp/error.c index 95b8b84f34..f7895dee64 100644 --- a/contrib/gcc-8.0/gcc/cp/error.c +++ b/contrib/gcc-8.0/gcc/cp/error.c @@ -3286,8 +3286,13 @@ void cxx_print_error_function (diagnostic_context *context, const char *file, diagnostic_info *diagnostic) { + char *prefix; + if (file) + prefix = xstrdup (file); + else + prefix = NULL; lhd_print_error_function (context, file, diagnostic); - pp_set_prefix (context->printer, file); + pp_set_prefix (context->printer, prefix); maybe_print_instantiation_context (context); } @@ -3315,7 +3320,7 @@ cp_print_error_function (diagnostic_context *context, return; if (diagnostic_last_function_changed (context, diagnostic)) { - const char *old_prefix = context->printer->prefix; + char *old_prefix = pp_take_prefix (context->printer); const char *file = LOCATION_FILE (diagnostic_location (diagnostic)); tree abstract_origin = diagnostic_abstract_origin (diagnostic); char *new_prefix = (file && abstract_origin == NULL) diff --git a/contrib/gcc-8.0/gcc/cp/expr.c b/contrib/gcc-8.0/gcc/cp/expr.c index 15894fc0b5..a9bf37bc67 100644 --- a/contrib/gcc-8.0/gcc/cp/expr.c +++ b/contrib/gcc-8.0/gcc/cp/expr.c @@ -139,6 +139,9 @@ mark_use (tree expr, bool rvalue_p, bool read_p, break; } } + temp_override l (input_location); + if (loc != UNKNOWN_LOCATION) + input_location = loc; expr = process_outer_var_ref (expr, tf_warning_or_error, true); if (!(TREE_TYPE (oexpr) && TREE_CODE (TREE_TYPE (oexpr)) == REFERENCE_TYPE)) @@ -183,6 +186,14 @@ mark_use (tree expr, bool rvalue_p, bool read_p, expr = convert_from_reference (r); } break; + + CASE_CONVERT: + case VIEW_CONVERT_EXPR: + if (location_wrapper_p (expr)) + loc = EXPR_LOCATION (expr); + recurse_op[0] = true; + break; + default: break; } diff --git a/contrib/gcc-8.0/gcc/cp/init.c b/contrib/gcc-8.0/gcc/cp/init.c index d6c0bcf8ce..302c603876 100644 --- a/contrib/gcc-8.0/gcc/cp/init.c +++ b/contrib/gcc-8.0/gcc/cp/init.c @@ -577,6 +577,16 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain) DECL_INSTANTIATING_NSDMI_P (member) = 1; + bool pushed = false; + if (!currently_open_class (DECL_CONTEXT (member))) + { + push_to_top_level (); + push_nested_class (DECL_CONTEXT (member)); + pushed = true; + } + + gcc_checking_assert (!processing_template_decl); + inject_this_parameter (DECL_CONTEXT (member), TYPE_UNQUALIFIED); start_lambda_scope (member); @@ -599,6 +609,12 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain) nsdmi_inst->put (member, init); } + if (pushed) + { + pop_nested_class (); + pop_from_top_level (); + } + input_location = sloc; cp_unevaluated_operand = un; } @@ -1678,6 +1694,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp)) { from_array = 1; + init = mark_rvalue_use (init); if (init && DECL_P (init) && !(flags & LOOKUP_ONLYCONVERTING)) { @@ -2856,10 +2873,9 @@ build_new_1 (vec **placement, tree type, tree nelts, outer_nelts_from_type = true; } - /* Lots of logic below. depends on whether we have a constant number of + /* Lots of logic below depends on whether we have a constant number of elements, so go ahead and fold it now. */ - if (outer_nelts) - outer_nelts = maybe_constant_value (outer_nelts); + const_tree cst_outer_nelts = fold_non_dependent_expr (outer_nelts); /* If our base type is an array, then make sure we know how many elements it has. */ @@ -2911,7 +2927,7 @@ build_new_1 (vec **placement, tree type, tree nelts, /* Warn if we performed the (T[N]) to T[N] transformation and N is variable. */ if (outer_nelts_from_type - && !TREE_CONSTANT (outer_nelts)) + && !TREE_CONSTANT (cst_outer_nelts)) { if (complain & tf_warning_or_error) { @@ -3010,9 +3026,9 @@ build_new_1 (vec **placement, tree type, tree nelts, size = size_binop (MULT_EXPR, size, fold_convert (sizetype, nelts)); - if (INTEGER_CST == TREE_CODE (outer_nelts)) + if (TREE_CODE (cst_outer_nelts) == INTEGER_CST) { - if (tree_int_cst_lt (max_outer_nelts_tree, outer_nelts)) + if (tree_int_cst_lt (max_outer_nelts_tree, cst_outer_nelts)) { /* When the array size is constant, check it at compile time to make sure it doesn't exceed the implementation-defined @@ -3638,13 +3654,13 @@ build_new (vec **placement, tree type, tree nelts, /* Try to determine the constant value only for the purposes of the diagnostic below but continue to use the original value and handle const folding later. */ - const_tree cst_nelts = maybe_constant_value (nelts); + const_tree cst_nelts = fold_non_dependent_expr (nelts); /* The expression in a noptr-new-declarator is erroneous if it's of non-class type and its value before converting to std::size_t is less than zero. ... If the expression is a constant expression, the program is ill-fomed. */ - if (INTEGER_CST == TREE_CODE (cst_nelts) + if (TREE_CODE (cst_nelts) == INTEGER_CST && tree_int_cst_sgn (cst_nelts) == -1) { if (complain & tf_error) @@ -4006,7 +4022,7 @@ build_vec_init (tree base, tree maxindex, tree init, tree compound_stmt; int destroy_temps; tree try_block = NULL_TREE; - int num_initialized_elts = 0; + HOST_WIDE_INT num_initialized_elts = 0; bool is_global; tree obase = base; bool xvalue = false; @@ -4441,10 +4457,13 @@ build_vec_init (tree base, tree maxindex, tree init, if (e) { - int max = tree_to_shwi (maxindex)+1; - for (; num_initialized_elts < max; ++num_initialized_elts) + HOST_WIDE_INT last = tree_to_shwi (maxindex); + if (num_initialized_elts <= last) { tree field = size_int (num_initialized_elts); + if (num_initialized_elts != last) + field = build2 (RANGE_EXPR, sizetype, field, + size_int (last)); CONSTRUCTOR_APPEND_ELT (const_vec, field, e); } } diff --git a/contrib/gcc-8.0/gcc/cp/lambda.c b/contrib/gcc-8.0/gcc/cp/lambda.c index e9b962a8f3..6c04393f1b 100644 --- a/contrib/gcc-8.0/gcc/cp/lambda.c +++ b/contrib/gcc-8.0/gcc/cp/lambda.c @@ -262,6 +262,9 @@ is_capture_proxy (tree decl) && DECL_HAS_VALUE_EXPR_P (decl) && !DECL_ANON_UNION_VAR_P (decl) && !DECL_DECOMPOSITION_P (decl) + && !(DECL_ARTIFICIAL (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_OMP_PRIVATIZED_MEMBER (decl)) && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl))); } @@ -884,7 +887,7 @@ resolvable_dummy_lambda (tree object) && current_class_type && LAMBDA_TYPE_P (current_class_type) && lambda_function (current_class_type) - && DERIVED_FROM_P (type, current_nonlambda_class_type ())) + && DERIVED_FROM_P (type, nonlambda_method_basetype())) return CLASSTYPE_LAMBDA_EXPR (current_class_type); return NULL_TREE; @@ -949,30 +952,37 @@ current_nonlambda_function (void) return fn; } -/* Returns the method basetype of the innermost non-lambda function, or - NULL_TREE if none. */ +/* Returns the method basetype of the innermost non-lambda function, including + a hypothetical constructor if inside an NSDMI, or NULL_TREE if none. */ tree nonlambda_method_basetype (void) { - tree fn, type; if (!current_class_ref) return NULL_TREE; - type = current_class_type; + tree type = current_class_type; if (!type || !LAMBDA_TYPE_P (type)) return type; - /* Find the nearest enclosing non-lambda function. */ - fn = TYPE_NAME (type); - do - fn = decl_function_context (fn); - while (fn && LAMBDA_FUNCTION_P (fn)); - - if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) - return NULL_TREE; - - return TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); + while (true) + { + tree lam = CLASSTYPE_LAMBDA_EXPR (type); + tree ex = LAMBDA_EXPR_EXTRA_SCOPE (lam); + if (ex && TREE_CODE (ex) == FIELD_DECL) + /* Lambda in an NSDMI. */ + return DECL_CONTEXT (ex); + + tree fn = TYPE_CONTEXT (type); + if (!fn || TREE_CODE (fn) != FUNCTION_DECL + || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + /* No enclosing non-lambda method. */ + return NULL_TREE; + if (!LAMBDA_FUNCTION_P (fn)) + /* Found an enclosing non-lambda method. */ + return TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); + type = DECL_CONTEXT (fn); + } } /* Like current_scope, but looking through lambdas. */ @@ -1108,6 +1118,9 @@ maybe_add_lambda_conv_op (tree type) { tree new_node = copy_node (src); + /* Clear TREE_ADDRESSABLE on thunk arguments. */ + TREE_ADDRESSABLE (new_node) = 0; + if (!fn_args) fn_args = tgt = new_node; else @@ -1373,6 +1386,24 @@ record_lambda_scope (tree lambda) LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++; } +/* This lambda is an instantiation of a lambda in a template default argument + that got no LAMBDA_EXPR_EXTRA_SCOPE, so this shouldn't either. But we do + need to use and increment the global count to avoid collisions. */ + +void +record_null_lambda_scope (tree lambda) +{ + if (vec_safe_is_empty (lambda_scope_stack)) + record_lambda_scope (lambda); + else + { + tree_int *p = lambda_scope_stack->begin(); + LAMBDA_EXPR_EXTRA_SCOPE (lambda) = p->t; + LAMBDA_EXPR_DISCRIMINATOR (lambda) = p->i++; + } + gcc_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == NULL_TREE); +} + void finish_lambda_scope (void) { @@ -1446,8 +1477,10 @@ mark_const_cap_r (tree *t, int *walk_subtrees, void *data) { tree decl = DECL_EXPR_DECL (*t); if (is_constant_capture_proxy (decl)) - var = DECL_CAPTURED_VARIABLE (decl); - *walk_subtrees = 0; + { + var = DECL_CAPTURED_VARIABLE (decl); + *walk_subtrees = 0; + } } else if (is_constant_capture_proxy (*t)) var = DECL_CAPTURED_VARIABLE (*t); @@ -1486,8 +1519,8 @@ prune_lambda_captures (tree body) tree cap = *capp; if (tree var = var_to_maybe_prune (cap)) { - tree *use = *const_vars.get (var); - if (TREE_CODE (*use) == DECL_EXPR) + tree **use = const_vars.get (var); + if (use && TREE_CODE (**use) == DECL_EXPR) { /* All uses of this capture were folded away, leaving only the proxy declaration. */ @@ -1502,7 +1535,7 @@ prune_lambda_captures (tree body) *fieldp = DECL_CHAIN (*fieldp); /* And remove the capture proxy declaration. */ - *use = void_node; + **use = void_node; continue; } } diff --git a/contrib/gcc-8.0/gcc/cp/method.c b/contrib/gcc-8.0/gcc/cp/method.c index eaa930f7c5..d10f1a6d2b 100644 --- a/contrib/gcc-8.0/gcc/cp/method.c +++ b/contrib/gcc-8.0/gcc/cp/method.c @@ -1144,11 +1144,11 @@ static tree constructible_expr (tree to, tree from) { tree expr; + cp_unevaluated cp_uneval_guard; if (CLASS_TYPE_P (to)) { tree ctype = to; vec *args = NULL; - cp_unevaluated cp_uneval_guard; if (TREE_CODE (to) != REFERENCE_TYPE) to = cp_build_reference_type (to, /*rval*/false); tree ob = build_stub_object (to); @@ -1216,7 +1216,7 @@ is_trivially_xible (enum tree_code code, tree to, tree from) tree expr; expr = is_xible_helper (code, to, from, /*trivial*/true); - if (expr == error_mark_node) + if (expr == NULL_TREE || expr == error_mark_node) return false; tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL); return !nt; @@ -1843,8 +1843,12 @@ maybe_explain_implicit_delete (tree decl) if (!informed) { tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl); - tree parm_type = TREE_VALUE (parms); - bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); + bool const_p = false; + if (parms) + { + tree parm_type = TREE_VALUE (parms); + const_p = CP_TYPE_CONST_P (non_reference (parm_type)); + } tree raises = NULL_TREE; bool deleted_p = false; tree scope = push_scope (ctype); @@ -2405,7 +2409,7 @@ lazily_declare_fn (special_function_kind sfk, tree type) /* Add it to the class */ bool added = add_method (type, fn, false); - gcc_assert (added); + gcc_assert (added || errorcount); /* Add it to TYPE_FIELDS. */ if (sfk == sfk_destructor diff --git a/contrib/gcc-8.0/gcc/cp/name-lookup.c b/contrib/gcc-8.0/gcc/cp/name-lookup.c index 95a07b5671..4e8263b2f6 100644 --- a/contrib/gcc-8.0/gcc/cp/name-lookup.c +++ b/contrib/gcc-8.0/gcc/cp/name-lookup.c @@ -560,11 +560,14 @@ name_lookup::search_namespace (tree scope) /* Look in exactly namespace. */ bool found = search_namespace_only (scope); - - /* Recursively look in its inline children. */ - if (vec *inlinees = DECL_NAMESPACE_INLINEES (scope)) - for (unsigned ix = inlinees->length (); ix--;) - found |= search_namespace ((*inlinees)[ix]); + + /* Don't look into inline children, if we're looking for an + anonymous name -- it must be in the current scope, if anywhere. */ + if (name) + /* Recursively look in its inline children. */ + if (vec *inlinees = DECL_NAMESPACE_INLINEES (scope)) + for (unsigned ix = inlinees->length (); ix--;) + found |= search_namespace ((*inlinees)[ix]); if (found) mark_found (scope); @@ -1237,17 +1240,6 @@ get_class_binding_direct (tree klass, tree name, int type_or_fns) } else if (STAT_HACK_P (val)) val = STAT_DECL (val); - - if (val && TREE_CODE (val) == OVERLOAD - && TREE_CODE (OVL_FUNCTION (val)) == USING_DECL) - { - /* An overload with a dependent USING_DECL. Does the caller - want the USING_DECL or the functions? */ - if (type_or_fns < 0) - val = OVL_CHAIN (val); - else - val = OVL_FUNCTION (val); - } } else { @@ -2737,6 +2729,13 @@ check_local_shadow (tree decl) && (same_type_p (TREE_TYPE (old), TREE_TYPE (decl)) || (!dependent_type_p (TREE_TYPE (decl)) && !dependent_type_p (TREE_TYPE (old)) + /* If the new decl uses auto, we don't yet know + its type (the old type cannot be using auto + at this point, without also being + dependent). This is an indication we're + (now) doing the shadow checking too + early. */ + && !type_uses_auto (TREE_TYPE (decl)) && can_convert (TREE_TYPE (old), TREE_TYPE (decl), tf_none)))) warning_code = OPT_Wshadow_compatible_local; @@ -5864,10 +5863,21 @@ consider_binding_level (tree name, best_match &bm, && DECL_ANTICIPATED (d)) continue; + /* Skip compiler-generated variables (e.g. __for_begin/__for_end + within range for). */ + if (TREE_CODE (d) == VAR_DECL + && DECL_ARTIFICIAL (d)) + continue; + tree suggestion = DECL_NAME (d); if (!suggestion) continue; + /* Don't suggest names that are for anonymous aggregate types, as + they are an implementation detail generated by the compiler. */ + if (anon_aggrname_p (suggestion)) + continue; + const char *suggestion_str = IDENTIFIER_POINTER (suggestion); /* Ignore internal names with spaces in them. */ @@ -6624,6 +6634,14 @@ do_pushtag (tree name, tree type, tag_scope scope) { tree cs = current_scope (); + /* Avoid setting the lambda context to a current_function_decl that + we aren't actually inside, e.g. one set by push_access_scope + during tsubst_default_argument. */ + if (cs && TREE_CODE (cs) == FUNCTION_DECL + && LAMBDA_TYPE_P (type) + && !at_function_scope_p ()) + cs = DECL_CONTEXT (cs); + if (scope == ts_current || (cs && TREE_CODE (cs) == FUNCTION_DECL)) context = cs; @@ -6928,7 +6946,7 @@ do_push_to_top_level (void) scope_chain = s; current_function_decl = NULL_TREE; - vec_alloc (current_lang_base, 10); + current_lang_base = NULL; current_lang_name = lang_name_cplusplus; current_namespace = global_namespace; push_class_stack (); @@ -6948,7 +6966,7 @@ do_pop_from_top_level (void) invalidate_class_lookup_cache (); pop_class_stack (); - current_lang_base = 0; + release_tree_vector (current_lang_base); scope_chain = s->prev; FOR_EACH_VEC_SAFE_ELT (s->old_bindings, i, saved) diff --git a/contrib/gcc-8.0/gcc/cp/optimize.c b/contrib/gcc-8.0/gcc/cp/optimize.c index fdb1650939..df6421f919 100644 --- a/contrib/gcc-8.0/gcc/cp/optimize.c +++ b/contrib/gcc-8.0/gcc/cp/optimize.c @@ -46,6 +46,8 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first) /* We may have taken its address. */ TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm); + DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm); + /* The definition might have different constness. */ TREE_READONLY (cloned_parm) = TREE_READONLY (parm); @@ -59,6 +61,25 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first) DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm); } +/* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER + properly. */ + +static tree +cxx_copy_decl (tree decl, copy_body_data *id) +{ + tree copy = copy_decl_no_change (decl, id); + if (VAR_P (decl) + && DECL_HAS_VALUE_EXPR_P (decl) + && DECL_ARTIFICIAL (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_OMP_PRIVATIZED_MEMBER (decl)) + { + tree expr = DECL_VALUE_EXPR (copy); + walk_tree (&expr, copy_tree_body_r, id, NULL); + SET_DECL_VALUE_EXPR (copy, expr); + } + return copy; +} /* FN is a function in High GIMPLE form that has a complete body and no CFG. CLONE is a function whose body is to be set to a copy of FN, @@ -78,7 +99,7 @@ clone_body (tree clone, tree fn, void *arg_map) id.src_cfun = DECL_STRUCT_FUNCTION (fn); id.decl_map = static_cast *> (arg_map); - id.copy_decl = copy_decl_no_change; + id.copy_decl = cxx_copy_decl; id.transform_call_graph_edges = CB_CGE_DUPLICATE; id.transform_new_cfg = true; id.transform_return_to_modify = false; @@ -386,6 +407,8 @@ maybe_thunk_body (tree fn, bool force) gcc_assert (clone_parm); DECL_ABSTRACT_ORIGIN (clone_parm) = NULL; args[parmno] = clone_parm; + /* Clear TREE_ADDRESSABLE on thunk arguments. */ + TREE_ADDRESSABLE (clone_parm) = 0; clone_parm = TREE_CHAIN (clone_parm); } if (fn_parm_typelist) diff --git a/contrib/gcc-8.0/gcc/cp/parser.c b/contrib/gcc-8.0/gcc/cp/parser.c index d8ce28a6d6..18b09affb5 100644 --- a/contrib/gcc-8.0/gcc/cp/parser.c +++ b/contrib/gcc-8.0/gcc/cp/parser.c @@ -2243,7 +2243,7 @@ static tree cp_parser_default_argument static void cp_parser_function_body (cp_parser *, bool); static tree cp_parser_initializer - (cp_parser *, bool *, bool *); + (cp_parser *, bool *, bool *, bool = false); static cp_expr cp_parser_initializer_clause (cp_parser *, bool *); static cp_expr cp_parser_braced_list @@ -5609,6 +5609,9 @@ cp_parser_primary_expression (cp_parser *parser, } } + if (processing_template_decl && is_overloaded_fn (decl)) + lookup_keep (get_fns (decl), true); + decl = (finish_id_expression (id_expression, decl, parser->scope, idk, @@ -7147,14 +7150,19 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, else if (!args->is_empty () && is_overloaded_fn (postfix_expression)) { + /* We only need to look at the first function, + because all the fns share the attribute we're + concerned with (all member fns or all local + fns). */ tree fn = get_first_fn (postfix_expression); fn = STRIP_TEMPLATE (fn); /* Do not do argument dependent lookup if regular lookup finds a member function or a block-scope function declaration. [basic.lookup.argdep]/3 */ - if (!DECL_FUNCTION_MEMBER_P (fn) - && !DECL_LOCAL_FUNCTION_P (fn)) + if (!((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn)) + || DECL_FUNCTION_MEMBER_P (fn) + || DECL_LOCAL_FUNCTION_P (fn))) { koenig_p = true; if (!any_type_dependent_arguments_p (args)) @@ -7494,10 +7502,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, access (5.2.5) outside the member function body. */ if (postfix_expression != current_class_ref && scope != error_mark_node - && !(processing_template_decl - && current_class_type - && (same_type_ignoring_top_level_qualifiers_p - (scope, current_class_type)))) + && !currently_open_class (scope)) { scope = complete_type (scope); if (!COMPLETE_TYPE_P (scope) @@ -10358,7 +10363,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) "lambda capture initializers " "only available with -std=c++14 or -std=gnu++14"); capture_init_expr = cp_parser_initializer (parser, &direct, - &non_constant); + &non_constant, true); explicit_init_p = true; if (capture_init_expr == NULL_TREE) { @@ -10620,6 +10625,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) DECL_ARTIFICIAL (fco) = 1; /* Give the object parameter a different name. */ DECL_NAME (DECL_ARGUMENTS (fco)) = get_identifier ("__closure"); + DECL_LAMBDA_FUNCTION (fco) = 1; if (return_type) TYPE_HAS_LATE_RETURN_TYPE (TREE_TYPE (fco)) = 1; } @@ -12293,12 +12299,9 @@ cp_parser_init_statement (cp_parser* parser, tree *decl) cp_lexer_consume_token (parser->lexer); is_range_for = true; if (cxx_dialect < cxx11) - { - pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0, - "range-based % loops only available with " - "-std=c++11 or -std=gnu++11"); - *decl = error_mark_node; - } + pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0, + "range-based % loops only available with " + "-std=c++11 or -std=gnu++11"); } else /* The ';' is not consumed yet because we told @@ -19064,22 +19067,35 @@ cp_parser_using_directive (cp_parser* parser) /* Parse an asm-definition. + asm-qualifier: + volatile + inline + goto + + asm-qualifier-list: + asm-qualifier + asm-qualifier-list asm-qualifier + asm-definition: asm ( string-literal ) ; GNU Extension: asm-definition: - asm volatile [opt] ( string-literal ) ; - asm volatile [opt] ( string-literal : asm-operand-list [opt] ) ; - asm volatile [opt] ( string-literal : asm-operand-list [opt] - : asm-operand-list [opt] ) ; - asm volatile [opt] ( string-literal : asm-operand-list [opt] - : asm-operand-list [opt] + asm asm-qualifier-list [opt] ( string-literal ) ; + asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt] ) ; + asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt] + : asm-operand-list [opt] ) ; + asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt] + : asm-operand-list [opt] : asm-clobber-list [opt] ) ; - asm volatile [opt] goto ( string-literal : : asm-operand-list [opt] - : asm-clobber-list [opt] - : asm-goto-list ) ; */ + asm asm-qualifier-list [opt] ( string-literal : : asm-operand-list [opt] + : asm-clobber-list [opt] + : asm-goto-list ) ; + + The form with asm-goto-list is valid if and only if the asm-qualifier-list + contains goto, and is the only allowed form in that case. No duplicates are + allowed in an asm-qualifier-list. */ static void cp_parser_asm_definition (cp_parser* parser) @@ -19090,11 +19106,9 @@ cp_parser_asm_definition (cp_parser* parser) tree clobbers = NULL_TREE; tree labels = NULL_TREE; tree asm_stmt; - bool volatile_p = false; bool extended_p = false; bool invalid_inputs_p = false; bool invalid_outputs_p = false; - bool goto_p = false; required_token missing = RT_NONE; /* Look for the `asm' keyword. */ @@ -19107,24 +19121,67 @@ cp_parser_asm_definition (cp_parser* parser) cp_function_chain->invalid_constexpr = true; } - /* See if the next token is `volatile'. */ - if (cp_parser_allow_gnu_extensions_p (parser) - && cp_lexer_next_token_is_keyword (parser->lexer, RID_VOLATILE)) - { - /* Remember that we saw the `volatile' keyword. */ - volatile_p = true; - /* Consume the token. */ - cp_lexer_consume_token (parser->lexer); - } - if (cp_parser_allow_gnu_extensions_p (parser) - && parser->in_function_body - && cp_lexer_next_token_is_keyword (parser->lexer, RID_GOTO)) - { - /* Remember that we saw the `goto' keyword. */ - goto_p = true; - /* Consume the token. */ - cp_lexer_consume_token (parser->lexer); - } + /* Handle the asm-qualifier-list. */ + location_t volatile_loc = UNKNOWN_LOCATION; + location_t inline_loc = UNKNOWN_LOCATION; + location_t goto_loc = UNKNOWN_LOCATION; + + if (cp_parser_allow_gnu_extensions_p (parser) && parser->in_function_body) + for (;;) + { + cp_token *token = cp_lexer_peek_token (parser->lexer); + location_t loc = token->location; + switch (cp_lexer_peek_token (parser->lexer)->keyword) + { + case RID_VOLATILE: + if (volatile_loc) + { + error_at (loc, "duplicate asm qualifier %qT", token->u.value); + inform (volatile_loc, "first seen here"); + } + else + volatile_loc = loc; + cp_lexer_consume_token (parser->lexer); + continue; + + case RID_INLINE: + if (inline_loc) + { + error_at (loc, "duplicate asm qualifier %qT", token->u.value); + inform (inline_loc, "first seen here"); + } + else + inline_loc = loc; + cp_lexer_consume_token (parser->lexer); + continue; + + case RID_GOTO: + if (goto_loc) + { + error_at (loc, "duplicate asm qualifier %qT", token->u.value); + inform (goto_loc, "first seen here"); + } + else + goto_loc = loc; + cp_lexer_consume_token (parser->lexer); + continue; + + case RID_CONST: + case RID_RESTRICT: + error_at (loc, "%qT is not an asm qualifier", token->u.value); + cp_lexer_consume_token (parser->lexer); + continue; + + default: + break; + } + break; + } + + bool volatile_p = (volatile_loc != UNKNOWN_LOCATION); + bool inline_p = (inline_loc != UNKNOWN_LOCATION); + bool goto_p = (goto_loc != UNKNOWN_LOCATION); + /* Look for the opening `('. */ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return; @@ -19216,8 +19273,7 @@ cp_parser_asm_definition (cp_parser* parser) CPP_CLOSE_PAREN)) clobbers = cp_parser_asm_clobber_list (parser); } - else if (goto_p - && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)) + else if (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)) /* The labels are coming next. */ labels_p = true; @@ -19251,7 +19307,7 @@ cp_parser_asm_definition (cp_parser* parser) if (parser->in_function_body) { asm_stmt = finish_asm_stmt (volatile_p, string, outputs, - inputs, clobbers, labels); + inputs, clobbers, labels, inline_p); /* If the extended syntax was not used, mark the ASM_EXPR. */ if (!extended_p) { @@ -21601,7 +21657,8 @@ cp_parser_parameter_declaration (cp_parser *parser, parameter was introduced during cp_parser_parameter_declaration, change any implicit parameters introduced into packs. */ if (parser->implicit_template_parms - && (token->type == CPP_ELLIPSIS + && ((token->type == CPP_ELLIPSIS + && declarator_can_be_parameter_pack (declarator)) || (declarator && declarator->parameter_pack_p))) { int latest_template_parm_idx = TREE_VEC_LENGTH @@ -21860,7 +21917,7 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser, static tree cp_parser_initializer (cp_parser* parser, bool* is_direct_init, - bool* non_constant_p) + bool* non_constant_p, bool subexpression_p) { cp_token *token; tree init; @@ -21907,7 +21964,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init, init = error_mark_node; } - if (check_for_bare_parameter_packs (init)) + if (!subexpression_p && check_for_bare_parameter_packs (init)) init = error_mark_node; return init; @@ -22500,7 +22557,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) cp_ensure_no_oacc_routine (parser); /* Issue an error message if type-definitions are forbidden here. */ - cp_parser_check_type_definition (parser); + bool type_definition_ok_p = cp_parser_check_type_definition (parser); /* Remember that we are defining one more class. */ ++parser->num_classes_being_defined; /* Inside the class, surrounding template-parameter-lists do not @@ -22695,7 +22752,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) cp_default_arg_entry *e; tree save_ccp, save_ccr; - if (any_erroneous_template_args_p (type)) + if (!type_definition_ok_p || any_erroneous_template_args_p (type)) { /* Skip default arguments, NSDMIs, etc, in order to improve error recovery (c++/71169, c++/71832). */ @@ -25218,14 +25275,19 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns) return error_mark_node; } + attr_ns = canonicalize_attr_name (attr_ns); attr_id = canonicalize_attr_name (attr_id); attribute = build_tree_list (build_tree_list (attr_ns, attr_id), NULL_TREE); token = cp_lexer_peek_token (parser->lexer); } else if (attr_ns) - attribute = build_tree_list (build_tree_list (attr_ns, attr_id), - NULL_TREE); + { + attr_ns = canonicalize_attr_name (attr_ns); + attr_id = canonicalize_attr_name (attr_id); + attribute = build_tree_list (build_tree_list (attr_ns, attr_id), + NULL_TREE); + } else { attr_id = canonicalize_attr_name (attr_id); @@ -25417,7 +25479,7 @@ cp_parser_std_attribute_spec (cp_parser *parser) || !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)) cp_parser_skip_to_end_of_statement (parser); else - /* Warn about parsing c++11 attribute in non-c++1 mode, only + /* Warn about parsing c++11 attribute in non-c++11 mode, only when we are sure that we have actually parsed them. */ maybe_warn_cpp0x (CPP0X_ATTRIBUTES); } @@ -34847,7 +34909,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) static tree cp_parser_omp_for_loop_init (cp_parser *parser, tree &this_pre_body, - vec *for_block, + vec *&for_block, tree &init, tree &orig_init, tree &decl, diff --git a/contrib/gcc-8.0/gcc/cp/pt.c b/contrib/gcc-8.0/gcc/cp/pt.c index 9fb819722e..f1a8feef39 100644 --- a/contrib/gcc-8.0/gcc/cp/pt.c +++ b/contrib/gcc-8.0/gcc/cp/pt.c @@ -3843,8 +3843,10 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) cap; cap = TREE_CHAIN (cap)) cp_walk_tree (&TREE_VALUE (cap), &find_parameter_packs_r, ppd, ppd->visited); - /* Since we defer implicit capture, look in the body as well. */ + /* Since we defer implicit capture, look in the parms and body. */ tree fn = lambda_function (t); + cp_walk_tree (&TREE_TYPE (fn), &find_parameter_packs_r, ppd, + ppd->visited); cp_walk_tree (&DECL_SAVED_TREE (fn), &find_parameter_packs_r, ppd, ppd->visited); *walk_subtrees = 0; @@ -3865,6 +3867,17 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) return NULL_TREE; } + case IF_STMT: + cp_walk_tree (&IF_COND (t), &find_parameter_packs_r, + ppd, ppd->visited); + cp_walk_tree (&THEN_CLAUSE (t), &find_parameter_packs_r, + ppd, ppd->visited); + cp_walk_tree (&ELSE_CLAUSE (t), &find_parameter_packs_r, + ppd, ppd->visited); + /* Don't walk into IF_STMT_EXTRA_ARGS. */ + *walk_subtrees = 0; + return NULL_TREE; + default: return NULL_TREE; } @@ -4035,7 +4048,7 @@ make_pack_expansion (tree arg, tsubst_flags_t complain) Returns TRUE and emits an error if there were bare parameter packs, returns FALSE otherwise. */ bool -check_for_bare_parameter_packs (tree t) +check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */) { tree parameter_packs = NULL_TREE; struct find_parameter_pack_data ppd; @@ -4059,7 +4072,8 @@ check_for_bare_parameter_packs (tree t) if (parameter_packs) { - location_t loc = EXPR_LOC_OR_LOC (t, input_location); + if (loc == UNKNOWN_LOCATION) + loc = EXPR_LOC_OR_LOC (t, input_location); error_at (loc, "parameter packs not expanded with %<...%>:"); while (parameter_packs) { @@ -9370,8 +9384,15 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, return found; } - context = tsubst (DECL_CONTEXT (gen_tmpl), arglist, - complain, in_decl); + context = DECL_CONTEXT (gen_tmpl); + if (context && TYPE_P (context)) + { + context = tsubst_aggr_type (context, arglist, complain, in_decl, true); + context = complete_type (context); + } + else + context = tsubst (context, arglist, complain, in_decl); + if (context == error_mark_node) return error_mark_node; @@ -9829,6 +9850,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) break; case TYPEOF_TYPE: + case DECLTYPE_TYPE: case UNDERLYING_TYPE: if (pfd->include_nondeduced_p && for_each_template_parm (TYPE_VALUES_RAW (t), fn, data, @@ -9836,6 +9858,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) pfd->include_nondeduced_p, pfd->any_fn)) return error_mark_node; + *walk_subtrees = false; break; case FUNCTION_DECL: @@ -10852,6 +10875,10 @@ instantiate_class_template_1 (tree type) /* Mark the type as in the process of being defined. */ TYPE_BEING_DEFINED (type) = 1; + /* We may be in the middle of deferred access check. Disable + it now. */ + deferring_access_check_sentinel acs (dk_no_deferred); + /* Determine what specialization of the original template to instantiate. */ t = most_specialized_partial_spec (type, tf_warning_or_error); @@ -10891,10 +10918,6 @@ instantiate_class_template_1 (tree type) if (! push_tinst_level (type)) return type; - /* We may be in the middle of deferred access check. Disable - it now. */ - push_deferring_access_checks (dk_no_deferred); - int saved_unevaluated_operand = cp_unevaluated_operand; int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; @@ -11375,7 +11398,6 @@ instantiate_class_template_1 (tree type) maximum_field_alignment = saved_maximum_field_alignment; if (!fn_context) pop_from_top_level (); - pop_deferring_access_checks (); pop_tinst_level (); /* The vtable for a template class can be emitted in any translation @@ -14484,6 +14506,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) && !PLACEHOLDER_TYPE_CONSTRAINTS (r)) /* Break infinite recursion when substituting the constraints of a constrained placeholder. */; + else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM + && !PLACEHOLDER_TYPE_CONSTRAINTS (t) + && !CLASS_PLACEHOLDER_TEMPLATE (t) + && (arg = TEMPLATE_TYPE_PARM_INDEX (t), + r = TEMPLATE_PARM_DESCENDANTS (arg)) + && (TEMPLATE_PARM_LEVEL (r) + == TEMPLATE_PARM_LEVEL (arg) - levels)) + /* Cache the simple case of lowering a type parameter. */ + r = TREE_TYPE (r); else { r = copy_type (t); @@ -16683,7 +16714,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, do. */ if (VAR_P (decl)) DECL_TEMPLATE_INSTANTIATED (decl) = 1; - if (VAR_P (decl) + if (VAR_P (decl) && !DECL_NAME (decl) && ANON_AGGR_TYPE_P (TREE_TYPE (decl))) /* Anonymous aggregates are a special case. */ finish_anon_union (decl); @@ -16712,7 +16743,17 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, else { int const_init = false; + unsigned int cnt = 0; + tree first = NULL_TREE, ndecl = error_mark_node; maybe_push_decl (decl); + + if (VAR_P (decl) + && DECL_DECOMPOSITION_P (decl) + && TREE_TYPE (pattern_decl) != error_mark_node) + ndecl = tsubst_decomp_names (decl, pattern_decl, args, + complain, in_decl, &first, + &cnt); + if (VAR_P (decl) && DECL_PRETTY_FUNCTION_P (decl)) { @@ -16728,23 +16769,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, if (VAR_P (decl)) const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (pattern_decl)); - if (VAR_P (decl) - && DECL_DECOMPOSITION_P (decl) - && TREE_TYPE (pattern_decl) != error_mark_node) - { - unsigned int cnt; - tree first; - tree ndecl - = tsubst_decomp_names (decl, pattern_decl, args, - complain, in_decl, &first, &cnt); - if (ndecl != error_mark_node) - cp_maybe_mangle_decomp (ndecl, first, cnt); - cp_finish_decl (decl, init, const_init, NULL_TREE, 0); - if (ndecl != error_mark_node) - cp_finish_decomp (ndecl, first, cnt); - } - else - cp_finish_decl (decl, init, const_init, NULL_TREE, 0); + + if (ndecl != error_mark_node) + cp_maybe_mangle_decomp (ndecl, first, cnt); + + cp_finish_decl (decl, init, const_init, NULL_TREE, 0); + + if (ndecl != error_mark_node) + cp_finish_decomp (ndecl, first, cnt); } } } @@ -16794,6 +16826,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t); RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t); finish_range_for_decl (stmt, decl, expr); + if (decomp_first && decl != error_mark_node) + cp_finish_decomp (decl, decomp_first, decomp_cnt); } else { @@ -16965,7 +16999,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, tree labels = tsubst_copy_asm_operands (ASM_LABELS (t), args, complain, in_decl); tmp = finish_asm_stmt (ASM_VOLATILE_P (t), string, outputs, inputs, - clobbers, labels); + clobbers, labels, ASM_INLINE_P (t)); tree asm_expr = tmp; if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR) asm_expr = TREE_OPERAND (asm_expr, 0); @@ -17528,7 +17562,11 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t); if (LAMBDA_EXPR_EXTRA_SCOPE (t) == NULL_TREE) - LAMBDA_EXPR_EXTRA_SCOPE (r) = NULL_TREE; + /* A lambda in a default argument outside a class gets no + LAMBDA_EXPR_EXTRA_SCOPE, as specified by the ABI. But + tsubst_default_argument calls start_lambda_scope, so we need to + specifically ignore it here, and use the global scope. */ + record_null_lambda_scope (r); else record_lambda_scope (r); @@ -17633,6 +17671,17 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) register_parameter_specializations (oldfn, fn); + if (oldtmpl) + { + /* We might not partially instantiate some parts of the function, so + copy these flags from the original template. */ + language_function *ol = DECL_STRUCT_FUNCTION (oldfn)->language; + current_function_returns_value = ol->returns_value; + current_function_returns_null = ol->returns_null; + current_function_returns_abnormally = ol->returns_abnormally; + current_function_infinite_loop = ol->infinite_loop; + } + tsubst_expr (DECL_SAVED_TREE (oldfn), args, complain, r, /*constexpr*/false); @@ -18427,7 +18476,9 @@ tsubst_copy_and_build (tree t, /* Unsupported internal function with arguments. */ gcc_unreachable (); } - else if (TREE_CODE (function) == OFFSET_REF) + else if (TREE_CODE (function) == OFFSET_REF + || TREE_CODE (function) == DOTSTAR_EXPR + || TREE_CODE (function) == MEMBER_REF) ret = build_offset_ref_call_from_tree (function, &call_args, complain); else if (TREE_CODE (function) == COMPONENT_REF) @@ -18477,10 +18528,6 @@ tsubst_copy_and_build (tree t, CALL_EXPR_REVERSE_ARGS (function) = rev; if (thk) { - if (TREE_CODE (function) == CALL_EXPR) - CALL_FROM_THUNK_P (function) = true; - else - AGGR_INIT_FROM_THUNK_P (function) = true; /* The thunk location is not interesting. */ SET_EXPR_LOCATION (function, UNKNOWN_LOCATION); } @@ -18493,6 +18540,7 @@ tsubst_copy_and_build (tree t, case COND_EXPR: { tree cond = RECUR (TREE_OPERAND (t, 0)); + cond = mark_rvalue_use (cond); tree folded_cond = fold_non_dependent_expr (cond); tree exp1, exp2; @@ -18953,6 +19001,11 @@ tsubst_copy_and_build (tree t, case REQUIRES_EXPR: RETURN (tsubst_requires_expr (t, args, complain, in_decl)); + case RANGE_EXPR: + /* No need to substitute further, a RANGE_EXPR will always be built + with constant operands. */ + RETURN (t); + case NON_LVALUE_EXPR: case VIEW_CONVERT_EXPR: /* We should only see these for location wrapper nodes, or within @@ -20114,6 +20167,24 @@ try_array_deduction (tree tparms, tree targs, tree parm) /*nondeduced*/false, array_deduction_r); } +/* Returns how many levels of { } INIT contains. */ + +static int +braced_init_depth (tree init) +{ + if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init)) + return 0; + unsigned i; tree val; + unsigned max = 0; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, val) + { + unsigned elt_d = braced_init_depth (val); + if (elt_d > max) + max = elt_d; + } + return max + 1; +} + /* Most parms like fn_type_unification. If SUBR is 1, we're being called recursively (to unify the @@ -20349,6 +20420,10 @@ type_unification_real (tree tparms, if (uses_template_parms (parm)) continue; + /* Workaround for c++/80290: avoid combinatorial explosion on + deeply nested braced init-lists. */ + if (braced_init_depth (arg) > 2) + continue; if (check_non_deducible_conversion (parm, arg, strict, flags, explain_p)) return 1; @@ -20368,8 +20443,6 @@ type_unification_real (tree tparms, location_t save_loc = input_location; if (DECL_P (parm)) input_location = DECL_SOURCE_LOCATION (parm); - if (saw_undeduced == 1) - ++processing_template_decl; if (saw_undeduced == 1 && TREE_CODE (parm) == PARM_DECL @@ -20377,11 +20450,14 @@ type_unification_real (tree tparms, { /* The type of this non-type parameter depends on undeduced parameters. Don't try to use its default argument yet, + since we might deduce an argument for it on the next pass, but do check whether the arguments we already have cause substitution failure, so that that happens before we try later default arguments (78489). */ + ++processing_template_decl; tree type = tsubst (TREE_TYPE (parm), full_targs, complain, NULL_TREE); + --processing_template_decl; if (type == error_mark_node) arg = error_mark_node; else @@ -20389,10 +20465,27 @@ type_unification_real (tree tparms, } else { - arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE); + tree substed = NULL_TREE; + if (saw_undeduced == 1 && processing_template_decl == 0) + { + /* First instatiate in template context, in case we still + depend on undeduced template parameters. */ + ++processing_template_decl; + substed = tsubst_template_arg (arg, full_targs, complain, + NULL_TREE); + --processing_template_decl; + if (substed != error_mark_node + && !uses_template_parms (substed)) + /* We replaced all the tparms, substitute again out of + template context. */ + substed = NULL_TREE; + } + if (!substed) + substed = tsubst_template_arg (arg, full_targs, complain, + NULL_TREE); - if (!uses_template_parms (arg)) - arg = convert_template_argument (parm, arg, full_targs, + if (!uses_template_parms (substed)) + arg = convert_template_argument (parm, substed, full_targs, complain, i, NULL_TREE); else if (saw_undeduced == 1) arg = NULL_TREE; @@ -20400,8 +20493,6 @@ type_unification_real (tree tparms, arg = error_mark_node; } - if (saw_undeduced == 1) - --processing_template_decl; input_location = save_loc; *checks = get_deferred_access_checks (); pop_deferring_access_checks (); @@ -25203,6 +25294,7 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees, TREE_TYPE. */ case TREE_LIST: case TREE_VEC: + case NONTYPE_ARGUMENT_PACK: return NULL_TREE; case TEMPLATE_PARM_INDEX: @@ -26382,6 +26474,8 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain) targs = template_parms_to_args (tparms); fparms = tsubst_arg_types (fparms, tsubst_args, NULL_TREE, complain, ctor); + if (fparms == error_mark_node) + ok = false; fargs = tsubst (fargs, tsubst_args, complain, ctor); if (ci) ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor); @@ -26865,7 +26959,7 @@ type_uses_auto (tree type) them. */ if (uses_template_parms (type)) return for_each_template_parm (type, is_auto_r, /*data*/NULL, - /*visited*/NULL, /*nondeduced*/true); + /*visited*/NULL, /*nondeduced*/false); else return NULL_TREE; } diff --git a/contrib/gcc-8.0/gcc/cp/search.c b/contrib/gcc-8.0/gcc/cp/search.c index bfeaf2cc81..d4214d4198 100644 --- a/contrib/gcc-8.0/gcc/cp/search.c +++ b/contrib/gcc-8.0/gcc/cp/search.c @@ -192,6 +192,9 @@ lookup_base (tree t, tree base, base_access access, else { t = complete_type (TYPE_MAIN_VARIANT (t)); + if (dependent_type_p (t)) + if (tree open = currently_open_class (t)) + t = open; t_binfo = TYPE_BINFO (t); } @@ -1117,7 +1120,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type, /* Make sure we're looking for a member of the current instantiation in the right partial specialization. */ - if (flag_concepts && dependent_type_p (type)) + if (dependent_type_p (type)) if (tree t = currently_open_class (type)) type = t; @@ -1224,9 +1227,16 @@ lookup_field_fuzzy_info::fuzzy_lookup_field (tree type) for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { - if (!m_want_type_p || DECL_DECLARES_TYPE_P (field)) - if (DECL_NAME (field)) - m_candidates.safe_push (DECL_NAME (field)); + if (m_want_type_p && !DECL_DECLARES_TYPE_P (field)) + continue; + + if (!DECL_NAME (field)) + continue; + + if (is_lambda_ignored_entity (field)) + continue; + + m_candidates.safe_push (DECL_NAME (field)); } } diff --git a/contrib/gcc-8.0/gcc/cp/semantics.c b/contrib/gcc-8.0/gcc/cp/semantics.c index 4568bb96f3..a5460fa392 100644 --- a/contrib/gcc-8.0/gcc/cp/semantics.c +++ b/contrib/gcc-8.0/gcc/cp/semantics.c @@ -736,7 +736,7 @@ finish_if_stmt_cond (tree cond, tree if_stmt) && !instantiation_dependent_expression_p (cond) /* Wait until instantiation time, since only then COND has been converted to bool. */ - && TREE_TYPE (cond) == boolean_type_node) + && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node) { cond = instantiate_non_dependent_expr (cond); cond = cxx_constant_value (cond, NULL_TREE); @@ -1461,11 +1461,11 @@ finish_compound_stmt (tree stmt) /* Finish an asm-statement, whose components are a STRING, some OUTPUT_OPERANDS, some INPUT_OPERANDS, some CLOBBERS and some LABELS. Also note whether the asm-statement should be - considered volatile. */ + considered volatile, and whether it is asm inline. */ tree finish_asm_stmt (int volatile_p, tree string, tree output_operands, - tree input_operands, tree clobbers, tree labels) + tree input_operands, tree clobbers, tree labels, bool inline_p) { tree r; tree t; @@ -1619,6 +1619,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, output_operands, input_operands, clobbers, labels); ASM_VOLATILE_P (r) = volatile_p || noutputs == 0; + ASM_INLINE_P (r) = inline_p; r = maybe_cleanup_point_expr_void (r); return add_stmt (r); } @@ -2107,6 +2108,8 @@ finish_qualified_id_expr (tree qualifying_class, non-type template argument handling. */ if (processing_template_decl && (!currently_open_class (qualifying_class) + || TREE_CODE (expr) == IDENTIFIER_NODE + || TREE_CODE (expr) == TEMPLATE_ID_EXPR || TREE_CODE (expr) == BIT_NOT_EXPR)) expr = build_qualified_name (TREE_TYPE (expr), qualifying_class, expr, @@ -2702,13 +2705,14 @@ finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr, /* TODO: build_x_unary_op doesn't always honor the location. */ result.set_location (combined_loc); - tree result_ovl, expr_ovl; + if (result == error_mark_node) + return result; if (!(complain & tf_warning)) return result; - result_ovl = result; - expr_ovl = expr; + tree result_ovl = result; + tree expr_ovl = expr; if (!processing_template_decl) expr_ovl = cp_fully_fold (expr_ovl); @@ -3411,10 +3415,9 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) } /* In a lambda within a template, wait until instantiation - time to implicitly capture. */ + time to implicitly capture a dependent type. */ if (context == containing_function - && DECL_TEMPLATE_INFO (containing_function) - && uses_template_parms (DECL_TI_ARGS (containing_function))) + && dependent_type_p (TREE_TYPE (decl))) return decl; if (lambda_expr && VAR_P (decl) @@ -3781,9 +3784,10 @@ finish_id_expression (tree id_expression, return error_mark_node; if (!template_arg_p - && TREE_CODE (first_fn) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (first_fn) - && !shared_member_p (decl)) + && (TREE_CODE (first_fn) == USING_DECL + || (TREE_CODE (first_fn) == FUNCTION_DECL + && DECL_FUNCTION_MEMBER_P (first_fn) + && !shared_member_p (decl)))) { /* A set of member functions. */ decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0); @@ -7311,7 +7315,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t)) share_name = "threadprivate"; - else switch (cxx_omp_predetermined_sharing (t)) + else switch (cxx_omp_predetermined_sharing_1 (t)) { case OMP_CLAUSE_DEFAULT_UNSPECIFIED: break; @@ -8514,10 +8518,13 @@ finish_omp_cancel (tree clauses) tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF); if (ifc != NULL_TREE) { - tree type = TREE_TYPE (OMP_CLAUSE_IF_EXPR (ifc)); - ifc = fold_build2_loc (OMP_CLAUSE_LOCATION (ifc), NE_EXPR, - boolean_type_node, OMP_CLAUSE_IF_EXPR (ifc), - build_zero_cst (type)); + if (!processing_template_decl) + ifc = maybe_convert_cond (OMP_CLAUSE_IF_EXPR (ifc)); + else + ifc = build_x_binary_op (OMP_CLAUSE_LOCATION (ifc), NE_EXPR, + OMP_CLAUSE_IF_EXPR (ifc), ERROR_MARK, + integer_zero_node, ERROR_MARK, + NULL, tf_warning_or_error); } else ifc = boolean_true_node; diff --git a/contrib/gcc-8.0/gcc/cp/tree.c b/contrib/gcc-8.0/gcc/cp/tree.c index dbe84c08a8..76b20ce659 100644 --- a/contrib/gcc-8.0/gcc/cp/tree.c +++ b/contrib/gcc-8.0/gcc/cp/tree.c @@ -1051,8 +1051,10 @@ build_array_of_n_type (tree elt, int n) return build_cplus_array_type (elt, build_index_type (size_int (n - 1))); } -/* True iff T is an N3639 array of runtime bound (VLA). These were - approved for C++14 but then removed. */ +/* True iff T is an N3639 array of runtime bound (VLA). These were approved + for C++14 but then removed. This should only be used for N3639 + specifically; code wondering more generally if something is a VLA should use + vla_type_p. */ bool array_of_runtime_bound_p (tree t) @@ -1069,6 +1071,23 @@ array_of_runtime_bound_p (tree t) || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max))); } +/* True iff T is a variable length array. */ + +bool +vla_type_p (tree t) +{ + for (; t && TREE_CODE (t) == ARRAY_TYPE; + t = TREE_TYPE (t)) + if (tree dom = TYPE_DOMAIN (t)) + { + tree max = TYPE_MAX_VALUE (dom); + if (!potential_rvalue_constant_expression (max) + || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max))) + return true; + } + return false; +} + /* Return a reference type node referring to TO_TYPE. If RVAL is true, return an rvalue reference type, otherwise return an lvalue reference type. If a type node exists, reuse it, otherwise create @@ -1704,9 +1723,9 @@ strip_typedefs_expr (tree t, bool *remove_attributes) tree it; for (it = t; it; it = TREE_CHAIN (it)) { - tree val = strip_typedefs_expr (TREE_VALUE (t), remove_attributes); + tree val = strip_typedefs_expr (TREE_VALUE (it), remove_attributes); vec_safe_push (vec, val); - if (val != TREE_VALUE (t)) + if (val != TREE_VALUE (it)) changed = true; gcc_assert (TREE_PURPOSE (it) == NULL_TREE); } @@ -3000,7 +3019,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data_) /* Make a copy of this node. */ t = copy_tree_r (tp, walk_subtrees, NULL); if (TREE_CODE (*tp) == CALL_EXPR) - set_flags_from_callee (*tp); + if (!processing_template_decl) + set_flags_from_callee (*tp); if (data.clear_location && EXPR_HAS_LOCATION (*tp)) SET_EXPR_LOCATION (*tp, input_location); return t; @@ -3862,6 +3882,14 @@ cp_tree_equal (tree t1, tree t2) DEFERRED_NOEXCEPT_ARGS (t2))); break; + case USING_DECL: + if (DECL_DEPENDENT_P (t1) && DECL_DEPENDENT_P (t2)) + return (cp_tree_equal (USING_DECL_SCOPE (t1), + USING_DECL_SCOPE (t2)) + && cp_tree_equal (DECL_NAME (t1), + DECL_NAME (t2))); + return false; + default: break; } @@ -4047,15 +4075,26 @@ maybe_warn_parm_abi (tree t, location_t loc) || !deleted_copy_types->contains (t)) return; - warning_at (loc, OPT_Wabi, "the calling convention for %qT changes in " - "-fabi-version=12 (GCC 8)", t); - static bool explained = false; - if (!explained) + if ((flag_abi_version == 12 || warn_abi_version == 12) + && classtype_has_non_deleted_move_ctor (t)) { - inform (loc, " because all of its copy and move constructors " - "are deleted"); - explained = true; + bool w; + if (flag_abi_version > 12) + w = warning_at (loc, OPT_Wabi, "-fabi-version=13 (GCC 8.2) fixes the " + "calling convention for %qT, which was accidentally " + "changed in 8.1", t); + else + w = warning_at (loc, OPT_Wabi, "-fabi-version=12 (GCC 8.1) accident" + "ally changes the calling convention for %qT", t); + if (w) + inform (location_of (t), " declared here"); + return; } + + if (warning_at (loc, OPT_Wabi, "the calling convention for %qT changes in " + "-fabi-version=13 (GCC 8.2)", t)) + inform (location_of (t), " because all of its copy and move " + "constructors are deleted"); } /* Returns true iff copying an object of type T (including via move @@ -4090,6 +4129,7 @@ type_has_nontrivial_copy_init (const_tree type) bool saw_copy = false; bool saw_non_deleted = false; + bool saw_non_deleted_move = false; if (CLASSTYPE_LAZY_MOVE_CTOR (t)) saw_copy = saw_non_deleted = true; @@ -4121,19 +4161,27 @@ type_has_nontrivial_copy_init (const_tree type) break; } } + else if (move_fn_p (fn)) + if (!DECL_DELETED_FN (fn)) + saw_non_deleted_move = true; } gcc_assert (saw_copy); - if (saw_copy && !saw_non_deleted) - { - if (warn_abi && abi_version_crosses (12)) - remember_deleted_copy (t); - if (abi_version_at_least (12)) - return true; - } - - return false; + /* ABI v12 buggily ignored move constructors. */ + bool v11nontriv = false; + bool v12nontriv = !saw_non_deleted; + bool v13nontriv = !saw_non_deleted && !saw_non_deleted_move; + bool nontriv = (abi_version_at_least (13) ? v13nontriv + : flag_abi_version == 12 ? v12nontriv + : v11nontriv); + bool warn_nontriv = (warn_abi_version >= 13 ? v13nontriv + : warn_abi_version == 12 ? v12nontriv + : v11nontriv); + if (nontriv != warn_nontriv) + remember_deleted_copy (t); + + return nontriv; } else return 0; @@ -4908,6 +4956,14 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, } break; + case LAMBDA_EXPR: + /* Don't walk into the body of the lambda, but the capture initializers + are part of the enclosing context. */ + for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap; + cap = TREE_CHAIN (cap)) + WALK_SUBTREE (TREE_VALUE (cap)); + break; + default: return NULL_TREE; } diff --git a/contrib/gcc-8.0/gcc/cp/typeck.c b/contrib/gcc-8.0/gcc/cp/typeck.c index d881a95322..9ffea19fba 100644 --- a/contrib/gcc-8.0/gcc/cp/typeck.c +++ b/contrib/gcc-8.0/gcc/cp/typeck.c @@ -2421,7 +2421,13 @@ build_class_member_access_expr (cp_expr object, tree member, { tree temp = unary_complex_lvalue (ADDR_EXPR, object); if (temp) - object = cp_build_fold_indirect_ref (temp); + { + temp = cp_build_fold_indirect_ref (temp); + if (xvalue_p (object) && !xvalue_p (temp)) + /* Preserve xvalue kind. */ + temp = move (temp); + object = temp; + } } /* In [expr.ref], there is an explicit list of the valid choices for @@ -2788,7 +2794,12 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, expression is dependent. */ || (TREE_CODE (name) == SCOPE_REF && TYPE_P (TREE_OPERAND (name, 0)) - && dependent_scope_p (TREE_OPERAND (name, 0)))) + && dependent_scope_p (TREE_OPERAND (name, 0))) + /* If NAME is operator T where "T" is dependent, we can't + lookup until we instantiate the T. */ + || (TREE_CODE (name) == IDENTIFIER_NODE + && IDENTIFIER_CONV_OP_P (name) + && dependent_type_p (TREE_TYPE (name)))) { dependent: return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, @@ -4826,7 +4837,7 @@ cp_build_binary_op (location_t location, tree pfn0, delta0, e1, e2; if (TREE_SIDE_EFFECTS (op0)) - op0 = save_expr (op0); + op0 = cp_save_expr (op0); pfn0 = pfn_from_ptrmemfunc (op0); delta0 = delta_from_ptrmemfunc (op0); @@ -5108,6 +5119,7 @@ cp_build_binary_op (location_t location, } if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE) + && !processing_template_decl && sanitize_flags_p (SANITIZE_POINTER_COMPARE)) { op0 = save_expr (op0); @@ -5353,6 +5365,7 @@ cp_build_binary_op (location_t location, otherwise, it will be given type RESULT_TYPE. */ if (! converted) { + warning_sentinel w (warn_sign_conversion, short_compare); if (TREE_TYPE (op0) != result_type) op0 = cp_convert_and_check (result_type, op0, complain); if (TREE_TYPE (op1) != result_type) @@ -5519,7 +5532,8 @@ pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype, else inttype = restype; - if (sanitize_flags_p (SANITIZE_POINTER_SUBTRACT)) + if (!processing_template_decl + && sanitize_flags_p (SANITIZE_POINTER_SUBTRACT)) { op0 = save_expr (op0); op1 = save_expr (op1); @@ -9066,6 +9080,22 @@ maybe_warn_about_returning_address_of_local (tree retval) && !(TREE_STATIC (whats_returned) || TREE_PUBLIC (whats_returned))) { + if (VAR_P (whats_returned) + && DECL_DECOMPOSITION_P (whats_returned) + && DECL_DECOMP_BASE (whats_returned) + && DECL_HAS_VALUE_EXPR_P (whats_returned)) + { + /* When returning address of a structured binding, if the structured + binding is not a reference, continue normally, if it is a + reference, recurse on the initializer of the structured + binding. */ + tree base = DECL_DECOMP_BASE (whats_returned); + if (TREE_CODE (TREE_TYPE (base)) == REFERENCE_TYPE) + { + tree init = DECL_INITIAL (base); + return maybe_warn_about_returning_address_of_local (init); + } + } if (TREE_CODE (valtype) == REFERENCE_TYPE) warning_at (DECL_SOURCE_LOCATION (whats_returned), OPT_Wreturn_local_addr, diff --git a/contrib/gcc-8.0/gcc/cp/typeck2.c b/contrib/gcc-8.0/gcc/cp/typeck2.c index 37e7893610..b91c98d594 100644 --- a/contrib/gcc-8.0/gcc/cp/typeck2.c +++ b/contrib/gcc-8.0/gcc/cp/typeck2.c @@ -611,7 +611,7 @@ split_nonconstant_init_1 (tree dest, tree init) array_type_p = true; if ((TREE_SIDE_EFFECTS (init) && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) - || array_of_runtime_bound_p (type)) + || vla_type_p (type)) { /* For an array, we only need/want a single cleanup region rather than one per element. */ @@ -822,7 +822,7 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl)) { bool const_init; - value = fold_non_dependent_expr (value); + value = fold_non_dependent_expr (value, tf_warning_or_error); if (DECL_DECLARED_CONSTEXPR_P (decl) || (DECL_IN_AGGR_P (decl) && DECL_INITIALIZED_IN_CLASS_P (decl) @@ -861,7 +861,7 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) will perform the dynamic initialization. */ if (value != error_mark_node && (TREE_SIDE_EFFECTS (value) - || array_of_runtime_bound_p (type) + || vla_type_p (type) || ! reduced_constant_expression_p (value))) return split_nonconstant_init (decl, value); /* If the value is a constant, just put it in DECL_INITIAL. If DECL @@ -1364,6 +1364,9 @@ process_init_constructor_array (tree type, tree init, int nested, flags |= picflag_from_initializer (next); CONSTRUCTOR_APPEND_ELT (v, size_int (i), next); } + else + /* Don't bother checking all the other elements. */ + break; } CONSTRUCTOR_ELTS (init) = v; diff --git a/contrib/gcc-8.0/gcc/dce.c b/contrib/gcc-8.0/gcc/dce.c index e4d442c62b..ce2edc43ef 100644 --- a/contrib/gcc-8.0/gcc/dce.c +++ b/contrib/gcc-8.0/gcc/dce.c @@ -108,7 +108,10 @@ deletable_insn_p (rtx_insn *insn, bool fast, bitmap arg_stores) /* We can delete dead const or pure calls as long as they do not infinite loop. */ && (RTL_CONST_OR_PURE_CALL_P (insn) - && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))) + && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)) + /* Don't delete calls that may throw if we cannot do so. */ + && ((cfun->can_delete_dead_exceptions && can_alter_cfg) + || insn_nothrow_p (insn))) return find_call_stack_args (as_a (insn), false, fast, arg_stores); @@ -200,7 +203,9 @@ mark_insn (rtx_insn *insn, bool fast) && !df_in_progress && !SIBLING_CALL_P (insn) && (RTL_CONST_OR_PURE_CALL_P (insn) - && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))) + && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)) + && ((cfun->can_delete_dead_exceptions && can_alter_cfg) + || insn_nothrow_p (insn))) find_call_stack_args (as_a (insn), true, fast, NULL); } } @@ -572,7 +577,12 @@ delete_unmarked_insns (void) rtx turn_into_use = NULL_RTX; /* Always delete no-op moves. */ - if (noop_move_p (insn)) + if (noop_move_p (insn) + /* Unless the no-op move can throw and we are not allowed + to alter cfg. */ + && (!cfun->can_throw_non_call_exceptions + || (cfun->can_delete_dead_exceptions && can_alter_cfg) + || insn_nothrow_p (insn))) { if (RTX_FRAME_RELATED_P (insn)) turn_into_use @@ -615,12 +625,6 @@ delete_unmarked_insns (void) for the destination regs in order to avoid dangling notes. */ remove_reg_equal_equiv_notes_for_defs (insn); - /* If a pure or const call is deleted, this may make the cfg - have unreachable blocks. We rememeber this and call - delete_unreachable_blocks at the end. */ - if (CALL_P (insn)) - must_clean = true; - if (turn_into_use) { /* Don't remove frame related noop moves if they cary @@ -633,12 +637,15 @@ delete_unmarked_insns (void) } else /* Now delete the insn. */ - delete_insn_and_edges (insn); + must_clean |= delete_insn_and_edges (insn); } /* Deleted a pure or const call. */ if (must_clean) - delete_unreachable_blocks (); + { + delete_unreachable_blocks (); + free_dominance_info (CDI_DOMINATORS); + } } diff --git a/contrib/gcc-8.0/gcc/defaults.h b/contrib/gcc-8.0/gcc/defaults.h index 78a08a33f1..9035b333be 100644 --- a/contrib/gcc-8.0/gcc/defaults.h +++ b/contrib/gcc-8.0/gcc/defaults.h @@ -1282,6 +1282,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_PECOFF 0 #endif +#ifndef TARGET_COFF +#define TARGET_COFF 0 +#endif + #ifndef EH_RETURN_HANDLER_RTX #define EH_RETURN_HANDLER_RTX NULL #endif diff --git a/contrib/gcc-8.0/gcc/diagnostic-show-locus.c b/contrib/gcc-8.0/gcc/diagnostic-show-locus.c index bdf608a08b..9c567bde68 100644 --- a/contrib/gcc-8.0/gcc/diagnostic-show-locus.c +++ b/contrib/gcc-8.0/gcc/diagnostic-show-locus.c @@ -2000,7 +2000,7 @@ diagnostic_show_locus (diagnostic_context * context, context->last_location = loc; - const char *saved_prefix = pp_get_prefix (context->printer); + char *saved_prefix = pp_take_prefix (context->printer); pp_set_prefix (context->printer, NULL); layout layout (context, richloc, diagnostic_kind); diff --git a/contrib/gcc-8.0/gcc/diagnostic.c b/contrib/gcc-8.0/gcc/diagnostic.c index e22c17bc02..c61e0c4572 100644 --- a/contrib/gcc-8.0/gcc/diagnostic.c +++ b/contrib/gcc-8.0/gcc/diagnostic.c @@ -1063,7 +1063,6 @@ diagnostic_append_note (diagnostic_context *context, { diagnostic_info diagnostic; va_list ap; - const char *saved_prefix; rich_location richloc (line_table, location); va_start (ap, gmsgid); @@ -1073,7 +1072,7 @@ diagnostic_append_note (diagnostic_context *context, va_end (ap); return; } - saved_prefix = pp_get_prefix (context->printer); + char *saved_prefix = pp_take_prefix (context->printer); pp_set_prefix (context->printer, diagnostic_build_prefix (context, &diagnostic)); pp_format (context->printer, &diagnostic.message); diff --git a/contrib/gcc-8.0/gcc/dojump.c b/contrib/gcc-8.0/gcc/dojump.c index 9da8a0e309..3a57a21bdf 100644 --- a/contrib/gcc-8.0/gcc/dojump.c +++ b/contrib/gcc-8.0/gcc/dojump.c @@ -1214,15 +1214,15 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code, code = unsignedp ? unsigned_code : signed_code; /* If function pointers need to be "canonicalized" before they can - be reliably compared, then canonicalize them. - Only do this if *both* sides of the comparison are function pointers. - If one side isn't, we want a noncanonicalized comparison. See PR - middle-end/17564. */ + be reliably compared, then canonicalize them. Canonicalize the + expression when one of the operands is a function pointer. This + handles the case where the other operand is a void pointer. See + PR middle-end/17564. */ if (targetm.have_canonicalize_funcptr_for_compare () - && POINTER_TYPE_P (TREE_TYPE (treeop0)) - && POINTER_TYPE_P (TREE_TYPE (treeop1)) - && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))) - && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1)))) + && ((POINTER_TYPE_P (TREE_TYPE (treeop0)) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))) + || (POINTER_TYPE_P (TREE_TYPE (treeop1)) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1)))))) { rtx new_op0 = gen_reg_rtx (mode); rtx new_op1 = gen_reg_rtx (mode); diff --git a/contrib/gcc-8.0/gcc/dwarf2out.c b/contrib/gcc-8.0/gcc/dwarf2out.c index 620e66986b..0940959cb5 100644 --- a/contrib/gcc-8.0/gcc/dwarf2out.c +++ b/contrib/gcc-8.0/gcc/dwarf2out.c @@ -304,6 +304,10 @@ static unsigned int rnglist_idx; #define FUNC_BEGIN_LABEL "LFB" #endif +#ifndef FUNC_SECOND_SECT_LABEL +#define FUNC_SECOND_SECT_LABEL "LFSB" +#endif + #ifndef FUNC_END_LABEL #define FUNC_END_LABEL "LFE" #endif @@ -1219,21 +1223,24 @@ static void set_cur_line_info_table (section *); void dwarf2out_switch_text_section (void) { + char label[MAX_ARTIFICIAL_LABEL_BYTES]; section *sect; dw_fde_ref fde = cfun->fde; gcc_assert (cfun && fde && fde->dw_fde_second_begin == NULL); + ASM_GENERATE_INTERNAL_LABEL (label, FUNC_SECOND_SECT_LABEL, + current_function_funcdef_no); + + fde->dw_fde_second_begin = ggc_strdup (label); if (!in_cold_section_p) { fde->dw_fde_end = crtl->subsections.cold_section_end_label; - fde->dw_fde_second_begin = crtl->subsections.hot_section_label; fde->dw_fde_second_end = crtl->subsections.hot_section_end_label; } else { fde->dw_fde_end = crtl->subsections.hot_section_end_label; - fde->dw_fde_second_begin = crtl->subsections.cold_section_label; fde->dw_fde_second_end = crtl->subsections.cold_section_end_label; } have_multiple_function_sections = true; @@ -8156,6 +8163,11 @@ copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, decl_table_entry **slot = NULL; struct decl_table_entry *entry = NULL; + /* If DIE refers to a stub unfold that so we get the appropriate + DIE registered as orig in decl_table. */ + if (dw_die_ref c = get_AT_ref (die, DW_AT_signature)) + die = c; + if (decl_table) { /* Check if the entry has already been copied to UNIT. */ @@ -8709,6 +8721,33 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, decl_hash_type *decl_table) FOR_EACH_CHILD (die, c, copy_decls_walk (unit, c, decl_table)); } +/* Collect skeleton dies in DIE created by break_out_comdat_types already + and record them in DECL_TABLE. */ + +static void +collect_skeleton_dies (dw_die_ref die, decl_hash_type *decl_table) +{ + dw_die_ref c; + + if (dw_attr_node *a = get_AT (die, DW_AT_signature)) + { + dw_die_ref targ = AT_ref (a); + gcc_assert (targ->die_mark == 0 && targ->comdat_type_p); + decl_table_entry **slot + = decl_table->find_slot_with_hash (targ, + htab_hash_pointer (targ), + INSERT); + gcc_assert (*slot == HTAB_EMPTY_ENTRY); + /* Record in DECL_TABLE that TARG has been already copied + by remove_child_or_replace_with_skeleton. */ + decl_table_entry *entry = XCNEW (struct decl_table_entry); + entry->orig = targ; + entry->copy = die; + *slot = entry; + } + FOR_EACH_CHILD (die, c, collect_skeleton_dies (c, decl_table)); +} + /* Copy declarations for "unworthy" types into the new comdat section. Incomplete types, modified types, and certain other types aren't broken out into comdat sections of their own, so they don't have a signature, @@ -8720,6 +8759,7 @@ copy_decls_for_unworthy_types (dw_die_ref unit) { mark_dies (unit); decl_hash_type decl_table (10); + collect_skeleton_dies (unit, &decl_table); copy_decls_walk (unit, unit, &decl_table); unmark_dies (unit); } @@ -9013,8 +9053,10 @@ build_abbrev_table (dw_die_ref die, external_ref_hash_type *extern_map) struct external_ref *ref_p; gcc_assert (AT_ref (a)->comdat_type_p || AT_ref (a)->die_id.die_symbol); - ref_p = lookup_external_ref (extern_map, c); - if (ref_p->stub && ref_p->stub != die) + if (is_type_die (c) + && (ref_p = lookup_external_ref (extern_map, c)) + && ref_p->stub && ref_p->stub != die + && a->dw_attr != DW_AT_signature) change_AT_die_ref (a, ref_p->stub); else /* We aren't changing this reference, so mark it external. */ @@ -9982,7 +10024,15 @@ new_loc_list (dw_loc_descr_ref expr, const char *begin, var_loc_view vbegin, return retlist; } -/* Return true iff there's any nonzero view number in the loc list. */ +/* Return true iff there's any nonzero view number in the loc list. + + ??? When views are not enabled, we'll often extend a single range + to the entire function, so that we emit a single location + expression rather than a location list. With views, even with a + single range, we'll output a list if start or end have a nonzero + view. If we change this, we may want to stop splitting a single + range in dw_loc_list just because of a nonzero view, even if it + straddles across hot/cold partitions. */ static bool loc_list_has_views (dw_loc_list_ref list) @@ -11052,7 +11102,9 @@ output_comp_unit (dw_die_ref die, int output_if_empty, static inline bool want_pubnames (void) { - if (debug_info_level <= DINFO_LEVEL_TERSE) + if (debug_info_level <= DINFO_LEVEL_TERSE + /* Names and types go to the early debug part only. */ + || in_lto_p) return false; if (debug_generate_pub_sections != -1) return debug_generate_pub_sections; @@ -13128,6 +13180,8 @@ modified_type_die (tree type, int cv_quals, bool reverse, && TYPE_PRECISION (sizetype) == TYPE_PRECISION (size_type_node) && TYPE_UNSIGNED (sizetype) == TYPE_UNSIGNED (size_type_node)) qualified_type = size_type_node; + if (type == sizetype) + type = qualified_type; } /* If we do, then we can just use its DIE, if it exists. */ @@ -14383,6 +14437,10 @@ expansion_failed (tree expr, rtx rtl, char const *reason) } } +/* True if handling a former CONST by mem_loc_descriptor piecewise. */ + +static bool in_const_p; + /* Helper function for const_ok_for_output. */ static bool @@ -14405,6 +14463,7 @@ const_ok_for_output_1 (rtx rtl) one in a constant pool entry, so testing SYMBOL_REF_TLS_MODEL rather than DECL_THREAD_LOCAL_P is not just an optimization. */ if (flag_checking + && !in_const_p && (XVECLEN (rtl, 0) == 0 || GET_CODE (XVECEXP (rtl, 0, 0)) != SYMBOL_REF || SYMBOL_REF_TLS_MODEL (XVECEXP (rtl, 0, 0)) == TLS_MODEL_NONE)) @@ -14428,13 +14487,6 @@ const_ok_for_output_1 (rtx rtl) if (CONST_POLY_INT_P (rtl)) return false; - if (targetm.const_not_ok_for_debug_p (rtl)) - { - expansion_failed (NULL_TREE, rtl, - "Expression rejected for debug by the backend.\n"); - return false; - } - /* FIXME: Refer to PR60655. It is possible for simplification of rtl expressions in var tracking to produce such expressions. We should really identify / validate expressions @@ -14447,6 +14499,41 @@ const_ok_for_output_1 (rtx rtl) case NOT: case NEG: return false; + case PLUS: + { + /* Make sure SYMBOL_REFs/UNSPECs are at most in one of the + operands. */ + subrtx_var_iterator::array_type array; + bool first = false; + FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 0), ALL) + if (SYMBOL_REF_P (*iter) + || LABEL_P (*iter) + || GET_CODE (*iter) == UNSPEC) + { + first = true; + break; + } + if (!first) + return true; + FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 1), ALL) + if (SYMBOL_REF_P (*iter) + || LABEL_P (*iter) + || GET_CODE (*iter) == UNSPEC) + return false; + return true; + } + case MINUS: + { + /* Disallow negation of SYMBOL_REFs or UNSPECs when they + appear in the second operand of MINUS. */ + subrtx_var_iterator::array_type array; + FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 1), ALL) + if (SYMBOL_REF_P (*iter) + || LABEL_P (*iter) + || GET_CODE (*iter) == UNSPEC) + return false; + return true; + } default: return true; } @@ -15590,6 +15677,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, pool. */ case CONST: case SYMBOL_REF: + case UNSPEC: if (!is_a (mode, &int_mode) || (GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE #ifdef POINTERS_EXTEND_UNSIGNED @@ -15597,6 +15685,43 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, #endif )) break; + + if (GET_CODE (rtl) == UNSPEC) + { + /* If delegitimize_address couldn't do anything with the UNSPEC, we + can't express it in the debug info. This can happen e.g. with some + TLS UNSPECs. Allow UNSPECs formerly from CONST that the backend + approves. */ + bool not_ok = false; + + if (!in_const_p) + break; + + subrtx_var_iterator::array_type array; + FOR_EACH_SUBRTX_VAR (iter, array, rtl, ALL) + if (*iter != rtl && !CONSTANT_P (*iter)) + { + not_ok = true; + break; + } + + if (not_ok) + break; + + FOR_EACH_SUBRTX_VAR (iter, array, rtl, ALL) + if (!const_ok_for_output_1 (*iter)) + { + not_ok = true; + break; + } + + if (not_ok) + break; + + rtl = gen_rtx_CONST (GET_MODE (rtl), rtl); + goto symref; + } + if (GET_CODE (rtl) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE) { @@ -15644,8 +15769,13 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, } break; default: - mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), int_mode, - mem_mode, initialized); + { + bool save_in_const_p = in_const_p; + in_const_p = true; + mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), int_mode, + mem_mode, initialized); + in_const_p = save_in_const_p; + } break; } break; @@ -16265,7 +16395,6 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, case VEC_CONCAT: case VEC_DUPLICATE: case VEC_SERIES: - case UNSPEC: case HIGH: case FMA: case STRICT_LOW_PART: @@ -16273,9 +16402,6 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, case CONST_FIXED: case CLRSB: case CLOBBER: - /* If delegitimize_address couldn't do anything with the UNSPEC, we - can't express it in the debug info. This can happen e.g. with some - TLS UNSPECs. */ break; case CONST_STRING: @@ -16729,7 +16855,15 @@ secname_for_decl (const_tree decl) && DECL_SECTION_NAME (decl)) secname = DECL_SECTION_NAME (decl); else if (current_function_decl && DECL_SECTION_NAME (current_function_decl)) - secname = DECL_SECTION_NAME (current_function_decl); + { + if (in_cold_section_p) + { + section *sec = current_function_section (); + if (sec->common.flags & SECTION_NAMED) + return sec->named.name; + } + secname = DECL_SECTION_NAME (current_function_decl); + } else if (cfun && in_cold_section_p) secname = crtl->subsections.cold_section_label; else @@ -17090,7 +17224,13 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) of first partition and second one starting at the beginning of second partition. */ if (node == loc_list->last_before_switch - && (node != loc_list->first || loc_list->first->next) + && (node != loc_list->first || loc_list->first->next + /* If we are to emit a view number, we will emit + a loclist rather than a single location + expression for the entire function (see + loc_list_has_views), so we have to split the + range that straddles across partitions. */ + || !ZERO_VIEW_P (node->view)) && current_function_decl) { endname = cfun->fde->dw_fde_end; @@ -23858,6 +23998,10 @@ gen_label_die (tree decl, dw_die_ref context_die) static inline void add_call_src_coords_attributes (tree stmt, dw_die_ref die) { + /* We can end up with BUILTINS_LOCATION here. */ + if (RESERVED_LOCATION_P (BLOCK_SOURCE_LOCATION (stmt))) + return; + expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (stmt)); if (dwarf_version >= 3 || !dwarf_strict) @@ -24908,7 +25052,7 @@ gen_member_die (tree type, dw_die_ref context_die) the TREE node representing the appropriate (containing) type. */ /* First output info about the base classes. */ - if (binfo) + if (binfo && early_dwarf) { vec *accesses = BINFO_BASE_ACCESSES (binfo); int i; @@ -25364,11 +25508,8 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, generate debug info for the typedef. */ if (is_naming_typedef_decl (TYPE_NAME (type))) { - /* Use the DIE of the containing namespace as the parent DIE of - the type description DIE we want to generate. */ - if (DECL_CONTEXT (TYPE_NAME (type)) - && TREE_CODE (DECL_CONTEXT (TYPE_NAME (type))) == NAMESPACE_DECL) - context_die = get_context_die (DECL_CONTEXT (TYPE_NAME (type))); + /* Give typedefs the right scope. */ + context_die = scope_die_for (type, context_die); gen_decl_die (TYPE_NAME (type), NULL, NULL, context_die); return; @@ -26367,7 +26508,7 @@ dwarf2out_early_global_decl (tree decl) enough so that it lands in its own context. This avoids type pruning issues later on. */ if (context_die == NULL || is_declaration_die (context_die)) - dwarf2out_decl (context); + dwarf2out_early_global_decl (context); } /* Emit an abstract origin of a function first. This happens @@ -28461,7 +28602,7 @@ init_sections_and_labels (bool early_lto_debug) debug_str_section = get_section (DEBUG_LTO_STR_SECTION, DEBUG_STR_SECTION_FLAGS | SECTION_EXCLUDE, NULL); - if (!dwarf_split_debug_info && !dwarf2out_as_loc_support) + if (!dwarf_split_debug_info) debug_line_str_section = get_section (DEBUG_LTO_LINE_STR_SECTION, DEBUG_STR_SECTION_FLAGS | SECTION_EXCLUDE, NULL); @@ -31044,9 +31185,9 @@ dwarf2out_finish (const char *) if (*slot != HTAB_EMPTY_ENTRY) continue; - /* Add a pointer to the line table for the main compilation unit - so that the debugger can make sense of DW_AT_decl_file - attributes. */ + /* Remove the pointer to the line table. */ + remove_AT (ctnode->root_die, DW_AT_stmt_list); + if (debug_info_level >= DINFO_LEVEL_TERSE) reset_dies (ctnode->root_die); @@ -31063,6 +31204,11 @@ dwarf2out_finish (const char *) /* Remove indirect string decisions. */ debug_str_hash->traverse (NULL); + if (debug_line_str_hash) + { + debug_line_str_hash->traverse (NULL); + debug_line_str_hash = NULL; + } } #if ENABLE_ASSERT_CHECKING @@ -31071,6 +31217,8 @@ dwarf2out_finish (const char *) FOR_EACH_CHILD (die, c, gcc_assert (! c->die_mark)); } #endif + for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next) + resolve_addr (ctnode->root_die); resolve_addr (comp_unit_die ()); move_marked_base_types (); @@ -31319,8 +31467,8 @@ dwarf2out_finish (const char *) switch_to_section (debug_loc_section); if (dwarf_version >= 5) { - ASM_GENERATE_INTERNAL_LABEL (l1, DEBUG_LOC_SECTION_LABEL, 1); - ASM_GENERATE_INTERNAL_LABEL (l2, DEBUG_LOC_SECTION_LABEL, 2); + ASM_GENERATE_INTERNAL_LABEL (l1, DEBUG_LOC_SECTION_LABEL, 2); + ASM_GENERATE_INTERNAL_LABEL (l2, DEBUG_LOC_SECTION_LABEL, 3); if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) dw2_asm_output_data (4, 0xffffffff, "Initial length escape value indicating " @@ -31710,7 +31858,7 @@ dwarf2out_early_finish (const char *filename) /* When emitting DWARF5 .debug_line_str, move DW_AT_name and DW_AT_comp_dir into .debug_line_str section. */ - if (!dwarf2out_as_loc_support + if (!output_asm_line_debug_info () && dwarf_version >= 5 && DWARF5_USE_DEBUG_LINE_STR) { @@ -31821,10 +31969,10 @@ dwarf2out_early_finish (const char *filename) /* Do not generate DWARF assembler now when not producing LTO bytecode. */ if ((!flag_generate_lto && !flag_generate_offload) - /* FIXME: Disable debug info generation for PE-COFF targets since the + /* FIXME: Disable debug info generation for (PE-)COFF targets since the copy_lto_debug_sections operation of the simple object support in libiberty is not implemented for them yet. */ - || TARGET_PECOFF) + || TARGET_PECOFF || TARGET_COFF) return; /* Now as we are going to output for LTO initialize sections and labels @@ -31939,6 +32087,13 @@ dwarf2out_early_finish (const char *filename) /* If we emitted any indirect strings, output the string table too. */ if (debug_str_hash || skeleton_debug_str_hash) output_indirect_strings (); + if (debug_line_str_hash) + { + switch_to_section (debug_line_str_section); + const enum dwarf_form form = DW_FORM_line_strp; + debug_line_str_hash->traverse (form); + } /* Switch back to the text section. */ switch_to_section (text_section); diff --git a/contrib/gcc-8.0/gcc/except.c b/contrib/gcc-8.0/gcc/except.c index ba42bf68b4..1243ee8dc6 100644 --- a/contrib/gcc-8.0/gcc/except.c +++ b/contrib/gcc-8.0/gcc/except.c @@ -1755,6 +1755,8 @@ copy_reg_eh_region_note_forward (rtx note_or_insn, rtx_insn *first, rtx last) if (note == NULL) return; } + else if (is_a (note_or_insn)) + return; note = XEXP (note, 0); for (insn = first; insn != last ; insn = NEXT_INSN (insn)) @@ -1777,6 +1779,8 @@ copy_reg_eh_region_note_backward (rtx note_or_insn, rtx_insn *last, rtx first) if (note == NULL) return; } + else if (is_a (note_or_insn)) + return; note = XEXP (note, 0); for (insn = last; insn != first; insn = PREV_INSN (insn)) diff --git a/contrib/gcc-8.0/gcc/expmed.c b/contrib/gcc-8.0/gcc/expmed.c index 4c74e7dc2e..fd16c1590f 100644 --- a/contrib/gcc-8.0/gcc/expmed.c +++ b/contrib/gcc-8.0/gcc/expmed.c @@ -3343,19 +3343,21 @@ expand_mult_const (machine_mode mode, rtx op0, HOST_WIDE_INT val, /* Write a REG_EQUAL note on the last insn so that we can cse multiplication sequences. Note that if ACCUM is a SUBREG, we've set the inner register and must properly indicate that. */ - tem = op0, nmode = mode; - accum_inner = accum; - if (GET_CODE (accum) == SUBREG) + tem = op0, nmode = mode; + accum_inner = accum; + if (GET_CODE (accum) == SUBREG) { accum_inner = SUBREG_REG (accum); nmode = GET_MODE (accum_inner); tem = gen_lowpart (nmode, op0); } - insn = get_last_insn (); - set_dst_reg_note (insn, REG_EQUAL, - gen_rtx_MULT (nmode, tem, - gen_int_mode (val_so_far, nmode)), + insn = get_last_insn (); + wide_int wval_so_far + = wi::uhwi (val_so_far, + GET_MODE_PRECISION (as_a (nmode))); + rtx c = immed_wide_int_const (wval_so_far, nmode); + set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c), accum_inner); } } @@ -4480,6 +4482,11 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode, HOST_WIDE_INT d = INTVAL (op1); unsigned HOST_WIDE_INT abs_d; + /* Not prepared to handle division/remainder by + 0xffffffffffffffff8000000000000000 etc. */ + if (d == HOST_WIDE_INT_MIN && size > HOST_BITS_PER_WIDE_INT) + break; + /* Since d might be INT_MIN, we have to cast to unsigned HOST_WIDE_INT before negating to avoid undefined signed overflow. */ @@ -4522,9 +4529,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode, || (optab_handler (sdivmod_optab, int_mode) != CODE_FOR_nothing))) ; - else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d) - && (size <= HOST_BITS_PER_WIDE_INT - || abs_d != (unsigned HOST_WIDE_INT) d)) + else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)) { if (rem_flag) { @@ -6038,6 +6043,11 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, if (!HAVE_conditional_move) return 0; + /* Do not turn a trapping comparison into a non-trapping one. */ + if ((code != EQ && code != NE && code != UNEQ && code != LTGT) + && flag_trapping_math) + return 0; + /* Try using a setcc instruction for ORDERED/UNORDERED, followed by a conditional move. */ tem = emit_store_flag_1 (subtarget, first_code, op0, op1, mode, 0, diff --git a/contrib/gcc-8.0/gcc/expr.c b/contrib/gcc-8.0/gcc/expr.c index c9e6bf228a..bac0c787e4 100644 --- a/contrib/gcc-8.0/gcc/expr.c +++ b/contrib/gcc-8.0/gcc/expr.c @@ -1632,14 +1632,6 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method, if (may_use_call < 0) return pc_rtx; - /* Since x and y are passed to a libcall, mark the corresponding - tree EXPR as addressable. */ - tree y_expr = MEM_EXPR (y); - tree x_expr = MEM_EXPR (x); - if (y_expr) - mark_addressable (y_expr); - if (x_expr) - mark_addressable (x_expr); retval = emit_block_copy_via_libcall (x, y, size, method == BLOCK_OP_TAILCALL); } @@ -1885,6 +1877,15 @@ emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src, tree call_expr, dst_tree, src_tree, size_tree; machine_mode size_mode; + /* Since dst and src are passed to a libcall, mark the corresponding + tree EXPR as addressable. */ + tree dst_expr = MEM_EXPR (dst); + tree src_expr = MEM_EXPR (src); + if (dst_expr) + mark_addressable (dst_expr); + if (src_expr) + mark_addressable (src_expr); + dst_addr = copy_addr_to_reg (XEXP (dst, 0)); dst_addr = convert_memory_address (ptr_mode, dst_addr); dst_tree = make_tree (ptr_type_node, dst_addr); @@ -5145,12 +5146,12 @@ expand_assignment (tree to, tree from, bool nontemporal) gcc_checking_assert (COMPLEX_MODE_P (to_mode)); poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode); unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode); - if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE (to_rtx) - && COMPLEX_MODE_P (GET_MODE (to_rtx)) + if (TYPE_MODE (TREE_TYPE (from)) == to_mode && known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize)) result = store_expr (from, to_rtx, false, nontemporal, reversep); - else if (known_eq (bitsize, inner_bitsize) + else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode) + && known_eq (bitsize, inner_bitsize) && (known_eq (bitpos, 0) || known_eq (bitpos, inner_bitsize))) result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)), @@ -5230,6 +5231,21 @@ expand_assignment (tree to, tree from, bool nontemporal) emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true)); } } + /* For calls to functions returning variable length structures, if TO_RTX + is not a MEM, go through a MEM because we must not create temporaries + of the VLA type. */ + else if (!MEM_P (to_rtx) + && TREE_CODE (from) == CALL_EXPR + && COMPLETE_TYPE_P (TREE_TYPE (from)) + && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST) + { + rtx temp = assign_stack_temp (GET_MODE (to_rtx), + GET_MODE_SIZE (GET_MODE (to_rtx))); + result = store_field (temp, bitsize, bitpos, bitregion_start, + bitregion_end, mode1, from, get_alias_set (to), + nontemporal, reversep); + emit_move_insn (to_rtx, temp); + } else { if (MEM_P (to_rtx)) @@ -5970,10 +5986,11 @@ count_type_elements (const_tree type, bool for_ctor_p) static bool categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, + HOST_WIDE_INT *p_unique_nz_elts, HOST_WIDE_INT *p_init_elts, bool *p_complete) { unsigned HOST_WIDE_INT idx; - HOST_WIDE_INT nz_elts, init_elts, num_fields; + HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields; tree value, purpose, elt_type; /* Whether CTOR is a valid constant initializer, in accordance with what @@ -5983,6 +6000,7 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor); nz_elts = 0; + unique_nz_elts = 0; init_elts = 0; num_fields = 0; elt_type = NULL_TREE; @@ -6007,12 +6025,13 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, { case CONSTRUCTOR: { - HOST_WIDE_INT nz = 0, ic = 0; + HOST_WIDE_INT nz = 0, unz = 0, ic = 0; - bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &ic, - p_complete); + bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &unz, + &ic, p_complete); nz_elts += mult * nz; + unique_nz_elts += unz; init_elts += mult * ic; if (const_from_elts_p && const_p) @@ -6024,21 +6043,31 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, case REAL_CST: case FIXED_CST: if (!initializer_zerop (value)) - nz_elts += mult; + { + nz_elts += mult; + unique_nz_elts++; + } init_elts += mult; break; case STRING_CST: nz_elts += mult * TREE_STRING_LENGTH (value); + unique_nz_elts += TREE_STRING_LENGTH (value); init_elts += mult * TREE_STRING_LENGTH (value); break; case COMPLEX_CST: if (!initializer_zerop (TREE_REALPART (value))) - nz_elts += mult; + { + nz_elts += mult; + unique_nz_elts++; + } if (!initializer_zerop (TREE_IMAGPART (value))) - nz_elts += mult; - init_elts += mult; + { + nz_elts += mult; + unique_nz_elts++; + } + init_elts += 2 * mult; break; case VECTOR_CST: @@ -6050,7 +6079,10 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, { tree v = VECTOR_CST_ELT (value, i); if (!initializer_zerop (v)) - nz_elts += mult; + { + nz_elts += mult; + unique_nz_elts++; + } init_elts += mult; } } @@ -6060,6 +6092,7 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, { HOST_WIDE_INT tc = count_type_elements (elt_type, false); nz_elts += mult * tc; + unique_nz_elts += tc; init_elts += mult * tc; if (const_from_elts_p && const_p) @@ -6079,6 +6112,7 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, *p_complete = false; *p_nz_elts += nz_elts; + *p_unique_nz_elts += unique_nz_elts; *p_init_elts += init_elts; return const_p; @@ -6087,6 +6121,11 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, /* Examine CTOR to discover: * how many scalar fields are set to nonzero values, and place it in *P_NZ_ELTS; + * the same, but counting RANGE_EXPRs as multiplier of 1 instead of + high - low + 1 (this can be useful for callers to determine ctors + that could be cheaply initialized with - perhaps nested - loops + compared to copied from huge read-only data), + and place it in *P_UNIQUE_NZ_ELTS; * how many scalar fields in total are in CTOR, and place it in *P_ELT_COUNT. * whether the constructor is complete -- in the sense that every @@ -6098,13 +6137,16 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, bool categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts, + HOST_WIDE_INT *p_unique_nz_elts, HOST_WIDE_INT *p_init_elts, bool *p_complete) { *p_nz_elts = 0; + *p_unique_nz_elts = 0; *p_init_elts = 0; *p_complete = true; - return categorize_ctor_elements_1 (ctor, p_nz_elts, p_init_elts, p_complete); + return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts, + p_init_elts, p_complete); } /* TYPE is initialized by a constructor with NUM_ELTS elements, the last @@ -6135,17 +6177,18 @@ complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts, return count_type_elements (type, true) == num_elts; } -/* Return 1 if EXP contains mostly (3/4) zeros. */ +/* Return 1 if EXP contains mostly (3/4) zeros. */ static int mostly_zeros_p (const_tree exp) { if (TREE_CODE (exp) == CONSTRUCTOR) { - HOST_WIDE_INT nz_elts, init_elts; + HOST_WIDE_INT nz_elts, unz_elts, init_elts; bool complete_p; - categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p); + categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts, + &complete_p); return !complete_p || nz_elts < init_elts / 4; } @@ -6159,10 +6202,11 @@ all_zeros_p (const_tree exp) { if (TREE_CODE (exp) == CONSTRUCTOR) { - HOST_WIDE_INT nz_elts, init_elts; + HOST_WIDE_INT nz_elts, unz_elts, init_elts; bool complete_p; - categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p); + categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts, + &complete_p); return nz_elts == 0; } @@ -8773,8 +8817,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, != INTEGER_CST check. Handle it. */ if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode) { - op0 = convert_modes (innermode, mode, op0, true); - op1 = convert_modes (innermode, mode, op1, false); + op0 = convert_modes (mode, innermode, op0, true); + op1 = convert_modes (mode, innermode, op1, false); return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); } @@ -8796,7 +8840,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, if (TREE_CODE (treeop0) != INTEGER_CST) { if (find_widening_optab_handler (this_optab, mode, innermode) - != CODE_FOR_nothing) + != CODE_FOR_nothing) { expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); @@ -8805,9 +8849,9 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode) { widen_mult_const: - op0 = convert_modes (innermode, mode, op0, zextend_p); + op0 = convert_modes (mode, innermode, op0, zextend_p); op1 - = convert_modes (innermode, mode, op1, + = convert_modes (mode, innermode, op1, TYPE_UNSIGNED (TREE_TYPE (treeop1))); return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, @@ -8818,21 +8862,19 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, return REDUCE_BIT_FIELD (temp); } if (find_widening_optab_handler (other_optab, mode, innermode) - != CODE_FOR_nothing + != CODE_FOR_nothing && innermode == word_mode) { rtx htem, hipart; op0 = expand_normal (treeop0); - if (TREE_CODE (treeop1) == INTEGER_CST) - op1 = convert_modes (word_mode, mode, - expand_normal (treeop1), - TYPE_UNSIGNED (TREE_TYPE (treeop1))); - else - op1 = expand_normal (treeop1); - /* op0 and op1 might still be constant, despite the above + op1 = expand_normal (treeop1); + /* op0 and op1 might be constants, despite the above != INTEGER_CST check. Handle it. */ if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode) goto widen_mult_const; + if (TREE_CODE (treeop1) == INTEGER_CST) + op1 = convert_modes (mode, word_mode, op1, + TYPE_UNSIGNED (TREE_TYPE (treeop1))); temp = expand_binop (mode, other_optab, op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); hipart = gen_highpart (word_mode, temp); @@ -11532,12 +11574,10 @@ do_store_flag (sepops ops, rtx target, machine_mode mode) /* We won't bother with store-flag operations involving function pointers when function pointers must be canonicalized before comparisons. */ if (targetm.have_canonicalize_funcptr_for_compare () - && ((TREE_CODE (TREE_TYPE (arg0)) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) - == FUNCTION_TYPE)) - || (TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) - == FUNCTION_TYPE)))) + && ((POINTER_TYPE_P (TREE_TYPE (arg0)) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0)))) + || (POINTER_TYPE_P (TREE_TYPE (arg1)) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1)))))) return 0; STRIP_NOPS (arg0); diff --git a/contrib/gcc-8.0/gcc/expr.h b/contrib/gcc-8.0/gcc/expr.h index 52a26e7c2a..49b2766eb6 100644 --- a/contrib/gcc-8.0/gcc/expr.h +++ b/contrib/gcc-8.0/gcc/expr.h @@ -308,7 +308,8 @@ extern bool can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int); extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree); extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *, - HOST_WIDE_INT *, bool *); + HOST_WIDE_INT *, HOST_WIDE_INT *, + bool *); extern void expand_operands (tree, tree, rtx, rtx*, rtx*, enum expand_modifier); diff --git a/contrib/gcc-8.0/gcc/final.c b/contrib/gcc-8.0/gcc/final.c index 19817e240d..5a65a8ce07 100644 --- a/contrib/gcc-8.0/gcc/final.c +++ b/contrib/gcc-8.0/gcc/final.c @@ -2306,6 +2306,9 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (cold_function_name)); #endif + if (dwarf2out_do_frame () + && cfun->fde->dw_fde_second_begin != NULL) + ASM_OUTPUT_LABEL (asm_out_file, cfun->fde->dw_fde_second_begin); } break; @@ -4673,7 +4676,11 @@ rest_of_handle_final (void) final_start_function_1 (&first, asm_out_file, &seen, optimize); final_1 (first, asm_out_file, seen, optimize); if (flag_ipa_ra - && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))) + && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl)) + /* Functions with naked attributes are supported only with basic asm + statements in the body, thus for supported use cases the information + on clobbered registers is not available. */ + && !lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))) collect_fn_hard_reg_usage (); final_end_function (); diff --git a/contrib/gcc-8.0/gcc/fold-const.c b/contrib/gcc-8.0/gcc/fold-const.c index 6472f10309..36bcc65f14 100644 --- a/contrib/gcc-8.0/gcc/fold-const.c +++ b/contrib/gcc-8.0/gcc/fold-const.c @@ -474,12 +474,15 @@ negate_expr_p (tree t) case EXACT_DIV_EXPR: if (TYPE_UNSIGNED (type)) break; - if (negate_expr_p (TREE_OPERAND (t, 0))) + /* In general we can't negate A in A / B, because if A is INT_MIN and + B is not 1 we change the sign of the result. */ + if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST + && negate_expr_p (TREE_OPERAND (t, 0))) return true; /* In general we can't negate B in A / B, because if A is INT_MIN and B is 1, we may turn this into INT_MIN / -1 which is undefined and actually traps on some architectures. */ - if (! INTEGRAL_TYPE_P (TREE_TYPE (t)) + if (! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t)) || TYPE_OVERFLOW_WRAPS (TREE_TYPE (t)) || (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST && ! integer_onep (TREE_OPERAND (t, 1)))) @@ -652,14 +655,17 @@ fold_negate_expr_1 (location_t loc, tree t) case EXACT_DIV_EXPR: if (TYPE_UNSIGNED (type)) break; - if (negate_expr_p (TREE_OPERAND (t, 0))) + /* In general we can't negate A in A / B, because if A is INT_MIN and + B is not 1 we change the sign of the result. */ + if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST + && negate_expr_p (TREE_OPERAND (t, 0))) return fold_build2_loc (loc, TREE_CODE (t), type, negate_expr (TREE_OPERAND (t, 0)), TREE_OPERAND (t, 1)); /* In general we can't negate B in A / B, because if A is INT_MIN and B is 1, we may turn this into INT_MIN / -1 which is undefined and actually traps on some architectures. */ - if ((! INTEGRAL_TYPE_P (TREE_TYPE (t)) + if ((! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t)) || TYPE_OVERFLOW_WRAPS (TREE_TYPE (t)) || (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST && ! integer_onep (TREE_OPERAND (t, 1)))) @@ -4916,8 +4922,8 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, /* Disable this optimization for function pointer expressions on targets that require function pointer canonicalization. */ if (targetm.have_canonicalize_funcptr_for_compare () - && TREE_CODE (etype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (etype)) == FUNCTION_TYPE) + && POINTER_TYPE_P (etype) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (etype))) return NULL_TREE; if (! in_p) @@ -5946,12 +5952,13 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type, } /* If the right sides are not constant, do the same for it. Also, - disallow this optimization if a size or signedness mismatch occurs - between the left and right sides. */ + disallow this optimization if a size, signedness or storage order + mismatch occurs between the left and right sides. */ if (l_const == 0) { if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp + || ll_reversep != lr_reversep /* Make sure the two fields on the right correspond to the left without being swapped. */ || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos) @@ -10792,8 +10799,7 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, strlen(ptr) != 0 => *ptr != 0 Other cases should reduce to one of these two (or a constant) due to the return value of strlen being unsigned. */ - if (TREE_CODE (arg0) == CALL_EXPR - && integer_zerop (arg1)) + if (TREE_CODE (arg0) == CALL_EXPR && integer_zerop (arg1)) { tree fndecl = get_callee_fndecl (arg0); @@ -10801,12 +10807,17 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN && call_expr_nargs (arg0) == 1 - && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (arg0, 0))) == POINTER_TYPE) + && (TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (arg0, 0))) + == POINTER_TYPE)) { - tree iref = build_fold_indirect_ref_loc (loc, - CALL_EXPR_ARG (arg0, 0)); + tree ptrtype + = build_pointer_type (build_qualified_type (char_type_node, + TYPE_QUAL_CONST)); + tree ptr = fold_convert_loc (loc, ptrtype, + CALL_EXPR_ARG (arg0, 0)); + tree iref = build_fold_indirect_ref_loc (loc, ptr); return fold_build2_loc (loc, code, type, iref, - build_int_cst (TREE_TYPE (iref), 0)); + build_int_cst (TREE_TYPE (iref), 0)); } } @@ -11559,10 +11570,16 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, && integer_pow2p (arg1) && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1), - arg1, OEP_ONLY_CONST)) + arg1, OEP_ONLY_CONST) + /* operand_equal_p compares just value, not precision, so e.g. + arg1 could be 8-bit -128 and be power of two, but BIT_AND_EXPR + second operand 32-bit -128, which is not a power of two (or vice + versa. */ + && integer_pow2p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))) return pedantic_non_lvalue_loc (loc, - fold_convert_loc (loc, type, - TREE_OPERAND (arg0, 0))); + fold_convert_loc (loc, type, + TREE_OPERAND (arg0, + 0))); /* Disable the transformations below for vectors, since fold_binary_op_with_conditional_arg may undo them immediately, diff --git a/contrib/gcc-8.0/gcc/function-tests.c b/contrib/gcc-8.0/gcc/function-tests.c index 1b5ebf3183..196b3a3828 100644 --- a/contrib/gcc-8.0/gcc/function-tests.c +++ b/contrib/gcc-8.0/gcc/function-tests.c @@ -661,6 +661,7 @@ test_expansion_to_rtl () ASSERT_STR_CONTAINS (dump, ") ;; function \"test_fn\"\n"); free (dump); + free_after_compilation (fun); } /* Run all of the selftests within this file. */ diff --git a/contrib/gcc-8.0/gcc/function.c b/contrib/gcc-8.0/gcc/function.c index 61515e38e4..d81e8b1ba8 100644 --- a/contrib/gcc-8.0/gcc/function.c +++ b/contrib/gcc-8.0/gcc/function.c @@ -6689,7 +6689,7 @@ match_asm_constraints_1 (rtx_insn *insn, rtx *p_sets, int noutputs) output_matched[match] = true; start_sequence (); - emit_move_insn (output, input); + emit_move_insn (output, copy_rtx (input)); insns = get_insns (); end_sequence (); emit_insn_before (insns, insn); diff --git a/contrib/gcc-8.0/gcc/gcov.c b/contrib/gcc-8.0/gcc/gcov.c index 6bbfe33ca3..c7c52ce362 100644 --- a/contrib/gcc-8.0/gcc/gcov.c +++ b/contrib/gcc-8.0/gcc/gcov.c @@ -536,6 +536,7 @@ static int process_args (int, char **); static void print_usage (int) ATTRIBUTE_NORETURN; static void print_version (void) ATTRIBUTE_NORETURN; static void process_file (const char *); +static void process_all_functions (void); static void generate_results (const char *); static void create_file_names (const char *); static char *canonicalize_name (const char *); @@ -791,6 +792,7 @@ main (int argc, char **argv) if (flag_intermediate_format || argno == argc - 1) { + process_all_functions (); generate_results (argv[argno]); release_structures (); } @@ -1066,7 +1068,8 @@ output_intermediate_file (FILE *gcov_file, source_info *src) } /* Follow with lines associated with the source file. */ - output_intermediate_line (gcov_file, &src->lines[line_num], line_num); + if (line_num < src->lines.size ()) + output_intermediate_line (gcov_file, &src->lines[line_num], line_num); } } @@ -1132,11 +1135,14 @@ process_file (const char *file_name) { create_file_names (file_name); read_graph_file (); - if (functions.empty ()) - return; - read_count_file (); +} +/* Process all functions in all files. */ + +static void +process_all_functions (void) +{ hash_map fn_map; /* Identify group functions. */ @@ -1213,7 +1219,6 @@ process_file (const char *file_name) if (fn->is_group) fn->lines.resize (fn->end_line - fn->start_line + 1); - solve_flow_graph (fn); if (fn->has_catch) find_exception_blocks (fn); diff --git a/contrib/gcc-8.0/gcc/gcse.c b/contrib/gcc-8.0/gcc/gcse.c index 8b9518e4f9..79d612dfa5 100644 --- a/contrib/gcc-8.0/gcc/gcse.c +++ b/contrib/gcc-8.0/gcc/gcse.c @@ -1963,14 +1963,11 @@ pre_expr_reaches_here_p (basic_block occr_bb, struct gcse_expr *expr, basic_bloc return rval; } -/* Generate RTL to copy an EXPR to its `reaching_reg' and return it. */ +/* Generate RTL to copy an EXP to REG and return it. */ -static rtx_insn * -process_insert_insn (struct gcse_expr *expr) +rtx_insn * +prepare_copy_insn (rtx reg, rtx exp) { - rtx reg = expr->reaching_reg; - /* Copy the expression to make sure we don't have any sharing issues. */ - rtx exp = copy_rtx (expr->expr); rtx_insn *pat; start_sequence (); @@ -1996,6 +1993,18 @@ process_insert_insn (struct gcse_expr *expr) return pat; } +/* Generate RTL to copy an EXPR to its `reaching_reg' and return it. */ + +static rtx_insn * +process_insert_insn (struct gcse_expr *expr) +{ + rtx reg = expr->reaching_reg; + /* Copy the expression to make sure we don't have any sharing issues. */ + rtx exp = copy_rtx (expr->expr); + + return prepare_copy_insn (reg, exp); +} + /* Add EXPR to the end of basic block BB. This is used by both the PRE and code hoisting. */ diff --git a/contrib/gcc-8.0/gcc/genmatch.c b/contrib/gcc-8.0/gcc/genmatch.c index be6efe3bf1..a75d8b3bb5 100644 --- a/contrib/gcc-8.0/gcc/genmatch.c +++ b/contrib/gcc-8.0/gcc/genmatch.c @@ -2680,12 +2680,14 @@ dt_operand::gen_match_op (FILE *f, int indent, const char *opname, bool) char match_opname[20]; match_dop->get_name (match_opname); if (value_match) - fprintf_indent (f, indent, "if (%s == %s || operand_equal_p (%s, %s, 0))\n", - opname, match_opname, opname, match_opname); + fprintf_indent (f, indent, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) " + "|| operand_equal_p (%s, %s, 0))\n", + opname, match_opname, opname, opname, match_opname); else - fprintf_indent (f, indent, "if (%s == %s || (operand_equal_p (%s, %s, 0) " + fprintf_indent (f, indent, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) " + "|| (operand_equal_p (%s, %s, 0) " "&& types_match (%s, %s)))\n", - opname, match_opname, opname, match_opname, + opname, match_opname, opname, opname, match_opname, opname, match_opname); fprintf_indent (f, indent + 2, "{\n"); return 1; diff --git a/contrib/gcc-8.0/gcc/gimple-fold.c b/contrib/gcc-8.0/gcc/gimple-fold.c index bd8c44a6a6..ee98ae5124 100644 --- a/contrib/gcc-8.0/gcc/gimple-fold.c +++ b/contrib/gcc-8.0/gcc/gimple-fold.c @@ -645,7 +645,7 @@ size_must_be_zero_p (tree size) if (integer_zerop (size)) return true; - if (TREE_CODE (size) != SSA_NAME) + if (TREE_CODE (size) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (size))) return false; wide_int min, max; @@ -3546,9 +3546,10 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi) return true; } - tree lhs = gimple_call_lhs (stmt); - if (lhs && TREE_CODE (lhs) == SSA_NAME) - set_range_info (lhs, VR_RANGE, minlen, maxlen); + if (tree lhs = gimple_call_lhs (stmt)) + if (TREE_CODE (lhs) == SSA_NAME + && INTEGRAL_TYPE_P (TREE_TYPE (lhs))) + set_range_info (lhs, VR_RANGE, minlen, maxlen); return false; } diff --git a/contrib/gcc-8.0/gcc/gimple-loop-interchange.cc b/contrib/gcc-8.0/gcc/gimple-loop-interchange.cc index eb35263e69..19510ad244 100644 --- a/contrib/gcc-8.0/gcc/gimple-loop-interchange.cc +++ b/contrib/gcc-8.0/gcc/gimple-loop-interchange.cc @@ -688,11 +688,16 @@ loop_cand::analyze_induction_var (tree var, tree chrec) /* Var is loop invariant, though it's unlikely to happen. */ if (tree_does_not_contain_chrecs (chrec)) { + /* Punt on floating point invariants if honoring signed zeros, + representing that as + 0.0 would change the result if init + is -0.0. Similarly for SNaNs it can raise exception. */ + if (HONOR_SIGNED_ZEROS (chrec) || HONOR_SNANS (chrec)) + return false; struct induction *iv = XCNEW (struct induction); iv->var = var; iv->init_val = init; iv->init_expr = chrec; - iv->step = build_int_cst (TREE_TYPE (chrec), 0); + iv->step = build_zero_cst (TREE_TYPE (chrec)); m_inductions.safe_push (iv); return true; } diff --git a/contrib/gcc-8.0/gcc/gimple-loop-jam.c b/contrib/gcc-8.0/gcc/gimple-loop-jam.c index 2ecd1bb5a7..381f3a8551 100644 --- a/contrib/gcc-8.0/gcc/gimple-loop-jam.c +++ b/contrib/gcc-8.0/gcc/gimple-loop-jam.c @@ -161,7 +161,7 @@ bb_prevents_fusion_p (basic_block bb) gimple_stmt_iterator gsi; /* BB is duplicated by outer unrolling and then all N-1 first copies move into the body of the fused inner loop. If BB exits the outer loop - the last copy still doess so, and the first N-1 copies are cancelled + the last copy still does so, and the first N-1 copies are cancelled by loop unrolling, so also after fusion it's the exit block. But there might be other reasons that prevent fusion: * stores or unknown side-effects prevent fusion @@ -227,6 +227,33 @@ unroll_jam_possible_p (struct loop *outer, struct loop *loop) || !expr_invariant_in_loop_p (outer, niter.niter)) return false; + /* If the inner loop produces any values that are used inside the + outer loop (except the virtual op) then it can flow + back (perhaps indirectly) into the inner loop. This prevents + fusion: without fusion the value at the last iteration is used, + with fusion the value after the initial iteration is used. + + If all uses are outside the outer loop this doesn't prevent fusion; + the value of the last iteration is still used (and the values from + all intermediate iterations are dead). */ + gphi_iterator psi; + for (psi = gsi_start_phis (single_exit (loop)->dest); + !gsi_end_p (psi); gsi_next (&psi)) + { + imm_use_iterator imm_iter; + use_operand_p use_p; + tree op = gimple_phi_result (psi.phi ()); + if (virtual_operand_p (op)) + continue; + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op) + { + gimple *use_stmt = USE_STMT (use_p); + if (!is_gimple_debug (use_stmt) + && flow_bb_inside_loop_p (outer, gimple_bb (use_stmt))) + return false; + } + } + /* And check blocks belonging to just outer loop. */ bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun)); n = get_loop_body_with_size (outer, bbs, n_basic_blocks_for_fn (cfun)); @@ -245,7 +272,6 @@ unroll_jam_possible_p (struct loop *outer, struct loop *loop) body would be the after-iter value of the first body) if it's over an associative and commutative operation. We wouldn't be able to handle unknown cycles. */ - gphi_iterator psi; for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi)) { affine_iv iv; @@ -429,7 +455,7 @@ tree_loop_unroll_and_jam (void) fprintf (dump_file, "Cannot analyze data dependencies\n"); free_data_refs (datarefs); free_dependence_relations (dependences); - return false; + continue; } if (!datarefs.length ()) continue; diff --git a/contrib/gcc-8.0/gcc/gimple-match-head.c b/contrib/gcc-8.0/gcc/gimple-match-head.c index 4266fb3d90..4e63c97e55 100644 --- a/contrib/gcc-8.0/gcc/gimple-match-head.c +++ b/contrib/gcc-8.0/gcc/gimple-match-head.c @@ -100,17 +100,34 @@ gimple_resimplify1 (gimple_seq *seq, } } + /* Limit recursion, there are cases like PR80887 and others, for + example when value-numbering presents us with unfolded expressions + that we are really not prepared to handle without eventual + oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50 + itself as available expression. */ + static unsigned depth; + if (depth > 10) + { + if (dump_file && (dump_flags & TDF_FOLDING)) + fprintf (dump_file, "Aborting expression simplification due to " + "deep recursion\n"); + return false; + } + + ++depth; code_helper res_code2; tree res_ops2[3] = {}; if (gimple_simplify (&res_code2, res_ops2, seq, valueize, *res_code, type, res_ops[0])) { + --depth; *res_code = res_code2; res_ops[0] = res_ops2[0]; res_ops[1] = res_ops2[1]; res_ops[2] = res_ops2[2]; return true; } + --depth; return false; } @@ -160,17 +177,30 @@ gimple_resimplify2 (gimple_seq *seq, canonicalized = true; } + /* Limit recursion, see gimple_resimplify1. */ + static unsigned depth; + if (depth > 10) + { + if (dump_file && (dump_flags & TDF_FOLDING)) + fprintf (dump_file, "Aborting expression simplification due to " + "deep recursion\n"); + return false; + } + + ++depth; code_helper res_code2; tree res_ops2[3] = {}; if (gimple_simplify (&res_code2, res_ops2, seq, valueize, *res_code, type, res_ops[0], res_ops[1])) { + --depth; *res_code = res_code2; res_ops[0] = res_ops2[0]; res_ops[1] = res_ops2[1]; res_ops[2] = res_ops2[2]; return true; } + --depth; return canonicalized; } @@ -219,18 +249,31 @@ gimple_resimplify3 (gimple_seq *seq, canonicalized = true; } + /* Limit recursion, see gimple_resimplify1. */ + static unsigned depth; + if (depth > 10) + { + if (dump_file && (dump_flags & TDF_FOLDING)) + fprintf (dump_file, "Aborting expression simplification due to " + "deep recursion\n"); + return false; + } + + ++depth; code_helper res_code2; tree res_ops2[3] = {}; if (gimple_simplify (&res_code2, res_ops2, seq, valueize, *res_code, type, res_ops[0], res_ops[1], res_ops[2])) { + --depth; *res_code = res_code2; res_ops[0] = res_ops2[0]; res_ops[1] = res_ops2[1]; res_ops[2] = res_ops2[2]; return true; } + --depth; return canonicalized; } diff --git a/contrib/gcc-8.0/gcc/gimple-pretty-print.c b/contrib/gcc-8.0/gcc/gimple-pretty-print.c index 6695526f37..487770f848 100644 --- a/contrib/gcc-8.0/gcc/gimple-pretty-print.c +++ b/contrib/gcc-8.0/gcc/gimple-pretty-print.c @@ -2040,6 +2040,8 @@ dump_gimple_asm (pretty_printer *buffer, gasm *gs, int spc, dump_flags_t flags) pp_string (buffer, "__asm__"); if (gimple_asm_volatile_p (gs)) pp_string (buffer, " __volatile__"); + if (gimple_asm_inline_p (gs)) + pp_string (buffer, " __inline__"); if (gimple_asm_nlabels (gs)) pp_string (buffer, " goto"); pp_string (buffer, "(\""); diff --git a/contrib/gcc-8.0/gcc/gimple-ssa-backprop.c b/contrib/gcc-8.0/gcc/gimple-ssa-backprop.c index 27aa575ab0..edbbae5394 100644 --- a/contrib/gcc-8.0/gcc/gimple-ssa-backprop.c +++ b/contrib/gcc-8.0/gcc/gimple-ssa-backprop.c @@ -260,6 +260,11 @@ private: post-order walk. */ auto_sbitmap m_visited_blocks; + /* A bitmap of phis that we have finished processing in the initial + post-order walk, excluding those from blocks mentioned in + M_VISITED_BLOCKS. */ + auto_bitmap m_visited_phis; + /* A worklist of SSA names whose definitions need to be reconsidered. */ auto_vec m_worklist; @@ -496,14 +501,18 @@ bool backprop::intersect_uses (tree var, usage_info *info) { imm_use_iterator iter; - gimple *stmt; + use_operand_p use_p; *info = usage_info::intersection_identity (); - FOR_EACH_IMM_USE_STMT (stmt, iter, var) + FOR_EACH_IMM_USE_FAST (use_p, iter, var) { + gimple *stmt = USE_STMT (use_p); if (is_gimple_debug (stmt)) continue; - if (is_a (stmt) - && !bitmap_bit_p (m_visited_blocks, gimple_bb (stmt)->index)) + gphi *phi = dyn_cast (stmt); + if (phi + && !bitmap_bit_p (m_visited_blocks, gimple_bb (phi)->index) + && !bitmap_bit_p (m_visited_phis, + SSA_NAME_VERSION (gimple_phi_result (phi)))) { /* Skip unprocessed phis. */ if (dump_file && (dump_flags & TDF_DETAILS)) @@ -511,7 +520,7 @@ backprop::intersect_uses (tree var, usage_info *info) fprintf (dump_file, "[BACKEDGE] "); print_generic_expr (dump_file, var); fprintf (dump_file, " in "); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); } } else @@ -520,10 +529,7 @@ backprop::intersect_uses (tree var, usage_info *info) process_use (stmt, var, &subinfo); *info &= subinfo; if (!info->is_useful ()) - { - BREAK_FROM_IMM_USE_STMT (iter); - return false; - } + return false; } } return true; @@ -635,7 +641,12 @@ backprop::process_block (basic_block bb) } for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi); gsi_next (&gpi)) - process_var (gimple_phi_result (gpi.phi ())); + { + tree result = gimple_phi_result (gpi.phi ()); + process_var (result); + bitmap_set_bit (m_visited_phis, SSA_NAME_VERSION (result)); + } + bitmap_clear (m_visited_phis); } /* Delete the definition of VAR, which has no uses. */ diff --git a/contrib/gcc-8.0/gcc/gimple-ssa-isolate-paths.c b/contrib/gcc-8.0/gcc/gimple-ssa-isolate-paths.c index 131705d182..1a81f85314 100644 --- a/contrib/gcc-8.0/gcc/gimple-ssa-isolate-paths.c +++ b/contrib/gcc-8.0/gcc/gimple-ssa-isolate-paths.c @@ -270,7 +270,7 @@ stmt_uses_name_in_undefined_way (gimple *use_stmt, tree name, location_t loc) divisor. */ if (!POINTER_TYPE_P (TREE_TYPE (name))) { - if (!flag_non_call_exceptions) + if (!cfun->can_throw_non_call_exceptions) return is_divmod_with_given_divisor (use_stmt, name); return false; } @@ -309,7 +309,7 @@ stmt_uses_name_in_undefined_way (gimple *use_stmt, tree name, location_t loc) bool stmt_uses_0_or_null_in_undefined_way (gimple *stmt) { - if (!flag_non_call_exceptions + if (!cfun->can_throw_non_call_exceptions && is_divmod_with_given_divisor (stmt, integer_zero_node)) return true; diff --git a/contrib/gcc-8.0/gcc/gimple-ssa-sprintf.c b/contrib/gcc-8.0/gcc/gimple-ssa-sprintf.c index 4ec58605ce..5cc4133aba 100644 --- a/contrib/gcc-8.0/gcc/gimple-ssa-sprintf.c +++ b/contrib/gcc-8.0/gcc/gimple-ssa-sprintf.c @@ -781,15 +781,19 @@ unsigned fmtresult::type_max_digits (tree type, int base) { unsigned prec = TYPE_PRECISION (type); - if (base == 8) - return (prec + 2) / 3; - - if (base == 16) - return prec / 4; + switch (base) + { + case 8: + return (prec + 2) / 3; + case 10: + /* Decimal approximation: yields 3, 5, 10, and 20 for precision + of 8, 16, 32, and 64 bits. */ + return prec * 301 / 1000 + 1; + case 16: + return prec / 4; + } - /* Decimal approximation: yields 3, 5, 10, and 20 for precision - of 8, 16, 32, and 64 bits. */ - return prec * 301 / 1000 + 1; + gcc_unreachable (); } static bool @@ -1759,6 +1763,11 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2]) unsigned flagmin = (1 /* for the first digit */ + (dir.get_flag ('+') | dir.get_flag (' '))); + /* The minimum is 3 for "inf" and "nan" for all specifiers, plus 1 + for the plus sign/space with the '+' and ' ' flags, respectively, + unless reduced below. */ + res.range.min = 2 + flagmin; + /* When the pound flag is set the decimal point is included in output regardless of precision. Whether or not a decimal point is included otherwise depends on the specification and precision. */ @@ -1775,14 +1784,13 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2]) else if (dir.prec[0] > 0) minprec = dir.prec[0] + !radix /* decimal point */; - res.range.min = (2 /* 0x */ - + flagmin - + radix - + minprec - + 3 /* p+0 */); + res.range.likely = (2 /* 0x */ + + flagmin + + radix + + minprec + + 3 /* p+0 */); res.range.max = format_floating_max (type, 'a', prec[1]); - res.range.likely = res.range.min; /* The unlikely maximum accounts for the longest multibyte decimal point character. */ @@ -1800,15 +1808,14 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2]) non-zero, decimal point. */ HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0; - /* The minimum output is "[-+]1.234567e+00" regardless + /* The likely minimum output is "[-+]1.234567e+00" regardless of the value of the actual argument. */ - res.range.min = (flagmin - + radix - + minprec - + 2 /* e+ */ + 2); + res.range.likely = (flagmin + + radix + + minprec + + 2 /* e+ */ + 2); res.range.max = format_floating_max (type, 'e', prec[1]); - res.range.likely = res.range.min; /* The unlikely maximum accounts for the longest multibyte decimal point character. */ @@ -1827,12 +1834,15 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2]) decimal point. */ HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0; - /* The lower bound when precision isn't specified is 8 bytes - ("1.23456" since precision is taken to be 6). When precision - is zero, the lower bound is 1 byte (e.g., "1"). Otherwise, - when precision is greater than zero, then the lower bound - is 2 plus precision (plus flags). */ - res.range.min = flagmin + radix + minprec; + /* For finite numbers (i.e., not infinity or NaN) the lower bound + when precision isn't specified is 8 bytes ("1.23456" since + precision is taken to be 6). When precision is zero, the lower + bound is 1 byte (e.g., "1"). Otherwise, when precision is greater + than zero, then the lower bound is 2 plus precision (plus flags). + But in all cases, the lower bound is no greater than 3. */ + unsigned HOST_WIDE_INT min = flagmin + radix + minprec; + if (min < res.range.min) + res.range.min = min; /* Compute the upper bound for -TYPE_MAX. */ res.range.max = format_floating_max (type, 'f', prec[1]); @@ -1842,7 +1852,7 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2]) if (dir.prec[0] < 0 && dir.prec[1] > 0) res.range.likely = 3; else - res.range.likely = res.range.min; + res.range.likely = min; /* The unlikely maximum accounts for the longest multibyte decimal point character. */ @@ -1860,7 +1870,9 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2]) the lower bound on the range of bytes (not counting flags or width) is 1 plus radix (i.e., either "0" or "0." for "%g" and "%#g", respectively, with a zero argument). */ - res.range.min = flagmin + radix; + unsigned HOST_WIDE_INT min = flagmin + radix; + if (min < res.range.min) + res.range.min = min; char spec = 'g'; HOST_WIDE_INT maxprec = dir.prec[1]; @@ -1992,6 +2004,32 @@ format_floating (const directive &dir, tree arg, vr_values *) const REAL_VALUE_TYPE *rvp = TREE_REAL_CST_PTR (arg); const real_format *rfmt = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg))); + if (!real_isfinite (rvp)) + { + /* The format for Infinity and NaN is "[-]inf"/"[-]infinity" + and "[-]nan" with the choice being implementation-defined + but not locale dependent. */ + bool sign = dir.get_flag ('+') || real_isneg (rvp); + res.range.min = 3 + sign; + + res.range.likely = res.range.min; + res.range.max = res.range.min; + /* The inlikely maximum is "[-/+]infinity" or "[-/+]nan". */ + res.range.unlikely = sign + (real_isinf (rvp) ? 8 : 3); + + /* The range for infinity and NaN is known unless either width + or precision is unknown. Width has the same effect regardless + of whether the argument is finite. Precision is either ignored + (e.g., Glibc) or can have an effect on the short vs long format + such as inf/infinity (e.g., Solaris). */ + res.knownrange = dir.known_width_and_precision (); + + /* Adjust the range for width but ignore precision. */ + res.adjust_for_width_or_precision (dir.width); + + return res; + } + char fmtstr [40]; char *pfmt = fmtstr; diff --git a/contrib/gcc-8.0/gcc/gimple-ssa-store-merging.c b/contrib/gcc-8.0/gcc/gimple-ssa-store-merging.c index 6f6538bf37..df7deb39ce 100644 --- a/contrib/gcc-8.0/gcc/gimple-ssa-store-merging.c +++ b/contrib/gcc-8.0/gcc/gimple-ssa-store-merging.c @@ -1416,6 +1416,7 @@ struct merged_store_group unsigned int load_align[2]; unsigned int first_order; unsigned int last_order; + unsigned int first_nonmergeable_order; auto_vec stores; /* We record the first and last original statements in the sequence because @@ -1806,6 +1807,7 @@ merged_store_group::merged_store_group (store_immediate_info *info) width has been finalized. */ val = NULL; mask = NULL; + first_nonmergeable_order = ~0U; unsigned HOST_WIDE_INT align_bitpos = 0; get_object_alignment_1 (gimple_assign_lhs (info->stmt), &align, &align_bitpos); @@ -2640,18 +2642,153 @@ imm_store_chain_info::coalesce_immediate_stores () } } + if (info->order >= merged_store->first_nonmergeable_order) + ; + /* |---store 1---| |---store 2---| Overlapping stores. */ - if (IN_RANGE (info->bitpos, merged_store->start, - merged_store->start + merged_store->width - 1)) + else if (IN_RANGE (info->bitpos, merged_store->start, + merged_store->start + merged_store->width - 1)) { /* Only allow overlapping stores of constants. */ if (info->rhs_code == INTEGER_CST && merged_store->stores[0]->rhs_code == INTEGER_CST) { - merged_store->merge_overlapping (info); - continue; + unsigned int last_order + = MAX (merged_store->last_order, info->order); + unsigned HOST_WIDE_INT end + = MAX (merged_store->start + merged_store->width, + info->bitpos + info->bitsize); + if (check_no_overlap (m_store_info, i, INTEGER_CST, + last_order, end)) + { + /* check_no_overlap call above made sure there are no + overlapping stores with non-INTEGER_CST rhs_code + in between the first and last of the stores we've + just merged. If there are any INTEGER_CST rhs_code + stores in between, we need to merge_overlapping them + even if in the sort_by_bitpos order there are other + overlapping stores in between. Keep those stores as is. + Example: + MEM[(int *)p_28] = 0; + MEM[(char *)p_28 + 3B] = 1; + MEM[(char *)p_28 + 1B] = 2; + MEM[(char *)p_28 + 2B] = MEM[(char *)p_28 + 6B]; + We can't merge the zero store with the store of two and + not merge anything else, because the store of one is + in the original order in between those two, but in + store_by_bitpos order it comes after the last store that + we can't merge with them. We can merge the first 3 stores + and keep the last store as is though. */ + unsigned int len = m_store_info.length (); + unsigned int try_order = last_order; + unsigned int first_nonmergeable_order; + unsigned int k; + bool last_iter = false; + int attempts = 0; + do + { + unsigned int max_order = 0; + unsigned first_nonmergeable_int_order = ~0U; + unsigned HOST_WIDE_INT this_end = end; + k = i; + first_nonmergeable_order = ~0U; + for (unsigned int j = i + 1; j < len; ++j) + { + store_immediate_info *info2 = m_store_info[j]; + if (info2->bitpos >= this_end) + break; + if (info2->order < try_order) + { + if (info2->rhs_code != INTEGER_CST) + { + /* Normally check_no_overlap makes sure this + doesn't happen, but if end grows below, + then we need to process more stores than + check_no_overlap verified. Example: + MEM[(int *)p_5] = 0; + MEM[(short *)p_5 + 3B] = 1; + MEM[(char *)p_5 + 4B] = _9; + MEM[(char *)p_5 + 2B] = 2; */ + k = 0; + break; + } + k = j; + this_end = MAX (this_end, + info2->bitpos + info2->bitsize); + } + else if (info2->rhs_code == INTEGER_CST + && !last_iter) + { + max_order = MAX (max_order, info2->order + 1); + first_nonmergeable_int_order + = MIN (first_nonmergeable_int_order, + info2->order); + } + else + first_nonmergeable_order + = MIN (first_nonmergeable_order, info2->order); + } + if (k == 0) + { + if (last_order == try_order) + break; + /* If this failed, but only because we grew + try_order, retry with the last working one, + so that we merge at least something. */ + try_order = last_order; + last_iter = true; + continue; + } + last_order = try_order; + /* Retry with a larger try_order to see if we could + merge some further INTEGER_CST stores. */ + if (max_order + && (first_nonmergeable_int_order + < first_nonmergeable_order)) + { + try_order = MIN (max_order, + first_nonmergeable_order); + try_order + = MIN (try_order, + merged_store->first_nonmergeable_order); + if (try_order > last_order && ++attempts < 16) + continue; + } + first_nonmergeable_order + = MIN (first_nonmergeable_order, + first_nonmergeable_int_order); + end = this_end; + break; + } + while (1); + + if (k != 0) + { + merged_store->merge_overlapping (info); + + merged_store->first_nonmergeable_order + = MIN (merged_store->first_nonmergeable_order, + first_nonmergeable_order); + + for (unsigned int j = i + 1; j <= k; j++) + { + store_immediate_info *info2 = m_store_info[j]; + gcc_assert (info2->bitpos < end); + if (info2->order < last_order) + { + gcc_assert (info2->rhs_code == INTEGER_CST); + if (info != info2) + merged_store->merge_overlapping (info2); + } + /* Other stores are kept and not merged in any + way. */ + } + ignore = k; + continue; + } + } } } /* |---store 1---||---store 2---| @@ -3343,6 +3480,8 @@ invert_op (split_store *split_store, int idx, tree int_type, tree &mask) bool imm_store_chain_info::output_merged_store (merged_store_group *group) { + split_store *split_store; + unsigned int i; unsigned HOST_WIDE_INT start_byte_pos = group->bitregion_start / BITS_PER_UNIT; @@ -3351,7 +3490,6 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) return false; auto_vec split_stores; - split_stores.create (0); bool allow_unaligned_store = !STRICT_ALIGNMENT && PARAM_VALUE (PARAM_STORE_MERGING_ALLOW_UNALIGNED); bool allow_unaligned_load = allow_unaligned_store; @@ -3378,6 +3516,8 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) fprintf (dump_file, "Exceeded original number of stmts (%u)." " Not profitable to emit new sequence.\n", orig_num_stmts); + FOR_EACH_VEC_ELT (split_stores, i, split_store) + delete split_store; return false; } if (total_orig <= total_new) @@ -3389,6 +3529,8 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) " not larger than estimated number of new" " stmts (%u).\n", total_orig, total_new); + FOR_EACH_VEC_ELT (split_stores, i, split_store) + delete split_store; return false; } @@ -3453,8 +3595,6 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) } gimple *stmt = NULL; - split_store *split_store; - unsigned int i; auto_vec orig_stmts; gimple_seq this_seq; tree addr = force_gimple_operand_1 (unshare_expr (base_addr), &this_seq, diff --git a/contrib/gcc-8.0/gcc/gimple-ssa-strength-reduction.c b/contrib/gcc-8.0/gcc/gimple-ssa-strength-reduction.c index 1c00f094db..edfebc281e 100644 --- a/contrib/gcc-8.0/gcc/gimple-ssa-strength-reduction.c +++ b/contrib/gcc-8.0/gcc/gimple-ssa-strength-reduction.c @@ -266,6 +266,10 @@ struct slsr_cand_d of a statement. */ cand_idx next_interp; + /* Index of the first candidate record in a chain for the same + statement. */ + cand_idx first_interp; + /* Index of the basis statement S0, if any, in the candidate vector. */ cand_idx basis; @@ -686,6 +690,7 @@ alloc_cand_and_find_basis (enum cand_kind kind, gimple *gs, tree base, c->kind = kind; c->cand_num = cand_vec.length () + 1; c->next_interp = 0; + c->first_interp = c->cand_num; c->dependent = 0; c->sibling = 0; c->def_phi = kind == CAND_MULT ? find_phi_def (base) : 0; @@ -1261,8 +1266,9 @@ slsr_process_mul (gimple *gs, tree rhs1, tree rhs2, bool speed) is the stride and RHS2 is the base expression. */ c2 = create_mul_ssa_cand (gs, rhs2, rhs1, speed); c->next_interp = c2->cand_num; + c2->first_interp = c->cand_num; } - else if (TREE_CODE (rhs2) == INTEGER_CST) + else if (TREE_CODE (rhs2) == INTEGER_CST && !integer_zerop (rhs2)) { /* Record an interpretation for the multiply-immediate. */ c = create_mul_imm_cand (gs, rhs1, rhs2, speed); @@ -1498,7 +1504,10 @@ slsr_process_add (gimple *gs, tree rhs1, tree rhs2, bool speed) { c2 = create_add_ssa_cand (gs, rhs2, rhs1, false, speed); if (c) - c->next_interp = c2->cand_num; + { + c->next_interp = c2->cand_num; + c2->first_interp = c->cand_num; + } else add_cand_for_stmt (gs, c2); } @@ -1621,6 +1630,8 @@ slsr_process_cast (gimple *gs, tree rhs1, bool speed) if (base_cand && base_cand->kind != CAND_PHI) { + slsr_cand_t first_cand = NULL; + while (base_cand) { /* Propagate all data from the base candidate except the type, @@ -1635,6 +1646,12 @@ slsr_process_cast (gimple *gs, tree rhs1, bool speed) base_cand->index, base_cand->stride, ctype, base_cand->stride_type, savings); + if (!first_cand) + first_cand = c; + + if (first_cand != c) + c->first_interp = first_cand->cand_num; + if (base_cand->next_interp) base_cand = lookup_cand (base_cand->next_interp); else @@ -1657,6 +1674,7 @@ slsr_process_cast (gimple *gs, tree rhs1, bool speed) c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, 0, integer_one_node, ctype, sizetype, 0); c->next_interp = c2->cand_num; + c2->first_interp = c->cand_num; } /* Add the first (or only) interpretation to the statement-candidate @@ -1681,6 +1699,8 @@ slsr_process_copy (gimple *gs, tree rhs1, bool speed) if (base_cand && base_cand->kind != CAND_PHI) { + slsr_cand_t first_cand = NULL; + while (base_cand) { /* Propagate all data from the base candidate. */ @@ -1693,6 +1713,12 @@ slsr_process_copy (gimple *gs, tree rhs1, bool speed) base_cand->index, base_cand->stride, base_cand->cand_type, base_cand->stride_type, savings); + if (!first_cand) + first_cand = c; + + if (first_cand != c) + c->first_interp = first_cand->cand_num; + if (base_cand->next_interp) base_cand = lookup_cand (base_cand->next_interp); else @@ -1717,6 +1743,7 @@ slsr_process_copy (gimple *gs, tree rhs1, bool speed) integer_one_node, TREE_TYPE (rhs1), sizetype, 0); c->next_interp = c2->cand_num; + c2->first_interp = c->cand_num; } /* Add the first (or only) interpretation to the statement-candidate @@ -1887,8 +1914,9 @@ dump_candidate (slsr_cand_t c) print_generic_expr (dump_file, c->cand_type); fprintf (dump_file, "\n basis: %d dependent: %d sibling: %d\n", c->basis, c->dependent, c->sibling); - fprintf (dump_file, " next-interp: %d dead-savings: %d\n", - c->next_interp, c->dead_savings); + fprintf (dump_file, + " next-interp: %d first-interp: %d dead-savings: %d\n", + c->next_interp, c->first_interp, c->dead_savings); if (c->def_phi) fprintf (dump_file, " phi: %d\n", c->def_phi); fputs ("\n", dump_file); @@ -2147,14 +2175,13 @@ replace_mult_candidate (slsr_cand_t c, tree basis_name, widest_int bump) tree lhs = gimple_assign_lhs (c->cand_stmt); gassign *copy_stmt = gimple_build_assign (lhs, basis_name); gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); - slsr_cand_t cc = c; + slsr_cand_t cc = lookup_cand (c->first_interp); gimple_set_location (copy_stmt, gimple_location (c->cand_stmt)); gsi_replace (&gsi, copy_stmt, false); - c->cand_stmt = copy_stmt; - while (cc->next_interp) + while (cc) { - cc = lookup_cand (cc->next_interp); cc->cand_stmt = copy_stmt; + cc = cc->next_interp ? lookup_cand (cc->next_interp) : NULL; } if (dump_file && (dump_flags & TDF_DETAILS)) stmt_to_print = copy_stmt; @@ -2181,14 +2208,13 @@ replace_mult_candidate (slsr_cand_t c, tree basis_name, widest_int bump) else { gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); - slsr_cand_t cc = c; + slsr_cand_t cc = lookup_cand (c->first_interp); gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree); update_stmt (gsi_stmt (gsi)); - c->cand_stmt = gsi_stmt (gsi); - while (cc->next_interp) + while (cc) { - cc = lookup_cand (cc->next_interp); cc->cand_stmt = gsi_stmt (gsi); + cc = cc->next_interp ? lookup_cand (cc->next_interp) : NULL; } if (dump_file && (dump_flags & TDF_DETAILS)) stmt_to_print = gsi_stmt (gsi); @@ -2753,17 +2779,23 @@ record_phi_increments_1 (slsr_cand_t basis, gimple *phi) for (i = 0; i < gimple_phi_num_args (phi); i++) { tree arg = gimple_phi_arg_def (phi, i); + gimple *arg_def = SSA_NAME_DEF_STMT (arg); - if (!operand_equal_p (arg, phi_cand->base_expr, 0)) + if (gimple_code (arg_def) == GIMPLE_PHI) + record_phi_increments_1 (basis, arg_def); + else { - gimple *arg_def = SSA_NAME_DEF_STMT (arg); + widest_int diff; - if (gimple_code (arg_def) == GIMPLE_PHI) - record_phi_increments_1 (basis, arg_def); + if (operand_equal_p (arg, phi_cand->base_expr, 0)) + { + diff = -basis->index; + record_increment (phi_cand, diff, PHI_ADJUST); + } else { slsr_cand_t arg_cand = base_cand_from_table (arg); - widest_int diff = arg_cand->index - basis->index; + diff = arg_cand->index - basis->index; record_increment (arg_cand, diff, PHI_ADJUST); } } @@ -2838,29 +2870,43 @@ phi_incr_cost_1 (slsr_cand_t c, const widest_int &incr, gimple *phi, for (i = 0; i < gimple_phi_num_args (phi); i++) { tree arg = gimple_phi_arg_def (phi, i); + gimple *arg_def = SSA_NAME_DEF_STMT (arg); - if (!operand_equal_p (arg, phi_cand->base_expr, 0)) + if (gimple_code (arg_def) == GIMPLE_PHI) { - gimple *arg_def = SSA_NAME_DEF_STMT (arg); - - if (gimple_code (arg_def) == GIMPLE_PHI) + int feeding_savings = 0; + tree feeding_var = gimple_phi_result (arg_def); + cost += phi_incr_cost_1 (c, incr, arg_def, &feeding_savings); + if (uses_consumed_by_stmt (feeding_var, phi)) + *savings += feeding_savings; + } + else + { + widest_int diff; + slsr_cand_t arg_cand; + + /* When the PHI argument is just a pass-through to the base + expression of the hidden basis, the difference is zero minus + the index of the basis. There is no potential savings by + eliminating a statement in this case. */ + if (operand_equal_p (arg, phi_cand->base_expr, 0)) { - int feeding_savings = 0; - tree feeding_var = gimple_phi_result (arg_def); - cost += phi_incr_cost_1 (c, incr, arg_def, &feeding_savings); - if (uses_consumed_by_stmt (feeding_var, phi)) - *savings += feeding_savings; + arg_cand = (slsr_cand_t)NULL; + diff = -basis->index; } else { - slsr_cand_t arg_cand = base_cand_from_table (arg); - widest_int diff = arg_cand->index - basis->index; - - if (incr == diff) + arg_cand = base_cand_from_table (arg); + diff = arg_cand->index - basis->index; + } + + if (incr == diff) + { + tree basis_lhs = gimple_assign_lhs (basis->cand_stmt); + cost += add_cost (true, TYPE_MODE (TREE_TYPE (basis_lhs))); + if (arg_cand) { - tree basis_lhs = gimple_assign_lhs (basis->cand_stmt); tree lhs = gimple_assign_lhs (arg_cand->cand_stmt); - cost += add_cost (true, TYPE_MODE (TREE_TYPE (basis_lhs))); if (uses_consumed_by_stmt (lhs, phi)) *savings += stmt_cost (arg_cand->cand_stmt, true); } @@ -3202,23 +3248,26 @@ ncd_with_phi (slsr_cand_t c, const widest_int &incr, gphi *phi, for (i = 0; i < gimple_phi_num_args (phi); i++) { tree arg = gimple_phi_arg_def (phi, i); + gimple *arg_def = SSA_NAME_DEF_STMT (arg); - if (!operand_equal_p (arg, phi_cand->base_expr, 0)) + if (gimple_code (arg_def) == GIMPLE_PHI) + ncd = ncd_with_phi (c, incr, as_a (arg_def), ncd, where); + else { - gimple *arg_def = SSA_NAME_DEF_STMT (arg); + widest_int diff; - if (gimple_code (arg_def) == GIMPLE_PHI) - ncd = ncd_with_phi (c, incr, as_a (arg_def), ncd, - where); - else + if (operand_equal_p (arg, phi_cand->base_expr, 0)) + diff = -basis->index; + else { slsr_cand_t arg_cand = base_cand_from_table (arg); - widest_int diff = arg_cand->index - basis->index; - basic_block pred = gimple_phi_arg_edge (phi, i)->src; - - if ((incr == diff) || (!address_arithmetic_p && incr == -diff)) - ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where); + diff = arg_cand->index - basis->index; } + + basic_block pred = gimple_phi_arg_edge (phi, i)->src; + + if ((incr == diff) || (!address_arithmetic_p && incr == -diff)) + ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where); } } @@ -3489,51 +3538,53 @@ all_phi_incrs_profitable_1 (slsr_cand_t c, gphi *phi, int *spread) return false; tree arg = gimple_phi_arg_def (phi, i); + gimple *arg_def = SSA_NAME_DEF_STMT (arg); - if (!operand_equal_p (arg, phi_cand->base_expr, 0)) + if (gimple_code (arg_def) == GIMPLE_PHI) { - gimple *arg_def = SSA_NAME_DEF_STMT (arg); + if (!all_phi_incrs_profitable_1 (c, as_a (arg_def), spread) + || *spread > MAX_SPREAD) + return false; + } + else + { + int j; + widest_int increment; - if (gimple_code (arg_def) == GIMPLE_PHI) - { - if (!all_phi_incrs_profitable_1 (c, as_a (arg_def), - spread) - || *spread > MAX_SPREAD) - return false; - } + if (operand_equal_p (arg, phi_cand->base_expr, 0)) + increment = -basis->index; else { - int j; slsr_cand_t arg_cand = base_cand_from_table (arg); - widest_int increment = arg_cand->index - basis->index; - - if (!address_arithmetic_p && wi::neg_p (increment)) - increment = -increment; + increment = arg_cand->index - basis->index; + } - j = incr_vec_index (increment); + if (!address_arithmetic_p && wi::neg_p (increment)) + increment = -increment; - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, " Conditional candidate %d, phi: ", - c->cand_num); - print_gimple_stmt (dump_file, phi, 0); - fputs (" increment: ", dump_file); - print_decs (increment, dump_file); - if (j < 0) - fprintf (dump_file, - "\n Not replaced; incr_vec overflow.\n"); - else { - fprintf (dump_file, "\n cost: %d\n", incr_vec[j].cost); - if (profitable_increment_p (j)) - fputs (" Replacing...\n", dump_file); - else - fputs (" Not replaced.\n", dump_file); - } - } + j = incr_vec_index (increment); - if (j < 0 || !profitable_increment_p (j)) - return false; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " Conditional candidate %d, phi: ", + c->cand_num); + print_gimple_stmt (dump_file, phi, 0); + fputs (" increment: ", dump_file); + print_decs (increment, dump_file); + if (j < 0) + fprintf (dump_file, + "\n Not replaced; incr_vec overflow.\n"); + else { + fprintf (dump_file, "\n cost: %d\n", incr_vec[j].cost); + if (profitable_increment_p (j)) + fputs (" Replacing...\n", dump_file); + else + fputs (" Not replaced.\n", dump_file); + } } + + if (j < 0 || !profitable_increment_p (j)) + return false; } } @@ -3597,14 +3648,13 @@ replace_rhs_if_not_dup (enum tree_code new_code, tree new_rhs1, tree new_rhs2, || !operand_equal_p (new_rhs2, old_rhs1, 0)))) { gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); - slsr_cand_t cc = c; + slsr_cand_t cc = lookup_cand (c->first_interp); gimple_assign_set_rhs_with_ops (&gsi, new_code, new_rhs1, new_rhs2); update_stmt (gsi_stmt (gsi)); - c->cand_stmt = gsi_stmt (gsi); - while (cc->next_interp) + while (cc) { - cc = lookup_cand (cc->next_interp); cc->cand_stmt = gsi_stmt (gsi); + cc = cc->next_interp ? lookup_cand (cc->next_interp) : NULL; } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -3637,6 +3687,11 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name) orig_rhs2 = gimple_assign_rhs2 (c->cand_stmt); cand_incr = cand_increment (c); + /* If orig_rhs2 is NULL, we have already replaced this in situ with + a copy statement under another interpretation. */ + if (!orig_rhs2) + return; + if (dump_file && (dump_flags & TDF_DETAILS)) { fputs ("Replacing: ", dump_file); @@ -3709,14 +3764,13 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name) || !operand_equal_p (rhs2, orig_rhs2, 0)) { gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); - slsr_cand_t cc = c; + slsr_cand_t cc = lookup_cand (c->first_interp); gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, basis_name, rhs2); update_stmt (gsi_stmt (gsi)); - c->cand_stmt = gsi_stmt (gsi); - while (cc->next_interp) + while (cc) { - cc = lookup_cand (cc->next_interp); cc->cand_stmt = gsi_stmt (gsi); + cc = cc->next_interp ? lookup_cand (cc->next_interp) : NULL; } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -3736,14 +3790,13 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name) { gassign *copy_stmt = gimple_build_assign (lhs, basis_name); gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); - slsr_cand_t cc = c; + slsr_cand_t cc = lookup_cand (c->first_interp); gimple_set_location (copy_stmt, gimple_location (c->cand_stmt)); gsi_replace (&gsi, copy_stmt, false); - c->cand_stmt = copy_stmt; - while (cc->next_interp) + while (cc) { - cc = lookup_cand (cc->next_interp); cc->cand_stmt = copy_stmt; + cc = cc->next_interp ? lookup_cand (cc->next_interp) : NULL; } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -3753,14 +3806,13 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name) { gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); gassign *cast_stmt = gimple_build_assign (lhs, NOP_EXPR, basis_name); - slsr_cand_t cc = c; + slsr_cand_t cc = lookup_cand (c->first_interp); gimple_set_location (cast_stmt, gimple_location (c->cand_stmt)); gsi_replace (&gsi, cast_stmt, false); - c->cand_stmt = cast_stmt; - while (cc->next_interp) + while (cc) { - cc = lookup_cand (cc->next_interp); cc->cand_stmt = cast_stmt; + cc = cc->next_interp ? lookup_cand (cc->next_interp) : NULL; } if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/contrib/gcc-8.0/gcc/gimple.h b/contrib/gcc-8.0/gcc/gimple.h index 265e3e2439..224463b33d 100644 --- a/contrib/gcc-8.0/gcc/gimple.h +++ b/contrib/gcc-8.0/gcc/gimple.h @@ -137,6 +137,7 @@ enum gimple_rhs_class enum gf_mask { GF_ASM_INPUT = 1 << 0, GF_ASM_VOLATILE = 1 << 1, + GF_ASM_INLINE = 1 << 2, GF_CALL_FROM_THUNK = 1 << 0, GF_CALL_RETURN_SLOT_OPT = 1 << 1, GF_CALL_TAILCALL = 1 << 2, @@ -3925,7 +3926,7 @@ gimple_asm_string (const gasm *asm_stmt) } -/* Return true ASM_STMT ASM_STMT is an asm statement marked volatile. */ +/* Return true if ASM_STMT is marked volatile. */ static inline bool gimple_asm_volatile_p (const gasm *asm_stmt) @@ -3934,7 +3935,7 @@ gimple_asm_volatile_p (const gasm *asm_stmt) } -/* If VOLATLE_P is true, mark asm statement ASM_STMT as volatile. */ +/* If VOLATILE_P is true, mark asm statement ASM_STMT as volatile. */ static inline void gimple_asm_set_volatile (gasm *asm_stmt, bool volatile_p) @@ -3946,6 +3947,27 @@ gimple_asm_set_volatile (gasm *asm_stmt, bool volatile_p) } +/* Return true if ASM_STMT is marked inline. */ + +static inline bool +gimple_asm_inline_p (const gasm *asm_stmt) +{ + return (asm_stmt->subcode & GF_ASM_INLINE) != 0; +} + + +/* If INLINE_P is true, mark asm statement ASM_STMT as inline. */ + +static inline void +gimple_asm_set_inline (gasm *asm_stmt, bool inline_p) +{ + if (inline_p) + asm_stmt->subcode |= GF_ASM_INLINE; + else + asm_stmt->subcode &= ~GF_ASM_INLINE; +} + + /* If INPUT_P is true, mark asm ASM_STMT as an ASM_INPUT. */ static inline void diff --git a/contrib/gcc-8.0/gcc/gimplify.c b/contrib/gcc-8.0/gcc/gimplify.c index c32869b4c5..12041973d8 100644 --- a/contrib/gcc-8.0/gcc/gimplify.c +++ b/contrib/gcc-8.0/gcc/gimplify.c @@ -4773,7 +4773,15 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { struct gimplify_init_ctor_preeval_data preeval_data; HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; + HOST_WIDE_INT num_unique_nonzero_elements; bool cleared, complete_p, valid_const_initializer; + /* Use readonly data for initializers of this or smaller size + regardless of the num_nonzero_elements / num_unique_nonzero_elements + ratio. */ + const HOST_WIDE_INT min_unique_size = 64; + /* If num_nonzero_elements / num_unique_nonzero_elements ratio + is smaller than this, use readonly data. */ + const int unique_nonzero_ratio = 8; /* Aggregate types must lower constructors to initialization of individual elements. The exception is that a CONSTRUCTOR node @@ -4790,6 +4798,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, can only do so if it known to be a valid constant initializer. */ valid_const_initializer = categorize_ctor_elements (ctor, &num_nonzero_elements, + &num_unique_nonzero_elements, &num_ctor_elements, &complete_p); /* If a const aggregate variable is being initialized, then it @@ -4798,7 +4807,15 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, && num_nonzero_elements > 1 && TREE_READONLY (object) && VAR_P (object) - && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))) + && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)) + /* For ctors that have many repeated nonzero elements + represented through RANGE_EXPRs, prefer initializing + those through runtime loops over copies of large amounts + of data from readonly data section. */ + && (num_unique_nonzero_elements + > num_nonzero_elements / unique_nonzero_ratio + || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) + <= (unsigned HOST_WIDE_INT) min_unique_size))) { if (notify_temp_creation) return GS_ERROR; @@ -4833,7 +4850,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, objects. Initializers for such objects must explicitly set every field that needs to be set. */ cleared = false; - else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor)) + else if (!complete_p) /* If the constructor isn't complete, clear the whole object beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it. @@ -4842,7 +4859,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, we'd need to *find* the elements that are not present, and that requires trickery to avoid quadratic compile-time behavior in large cases or excessive memory use in small cases. */ - cleared = true; + cleared = !CONSTRUCTOR_NO_CLEARING (ctor); else if (num_ctor_elements - num_nonzero_elements > CLEAR_RATIO (optimize_function_for_speed_p (cfun)) && num_nonzero_elements < num_ctor_elements / 4) @@ -4899,6 +4916,13 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, is so large as to make individual moves inefficient. */ if (size > 0 && num_nonzero_elements > 1 + /* For ctors that have many repeated nonzero elements + represented through RANGE_EXPRs, prefer initializing + those through runtime loops over copies of large amounts + of data from readonly data section. */ + && (num_unique_nonzero_elements + > num_nonzero_elements / unique_nonzero_ratio + || size <= min_unique_size) && (size < num_nonzero_elements || !can_move_by_pieces (size, align))) { @@ -5927,8 +5951,11 @@ gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) } else /* The temporary may not be an SSA name as later abnormal and EH - control flow may invalidate use/def domination. */ - val = get_initialized_tmp_var (val, pre_p, post_p, false); + control flow may invalidate use/def domination. When in SSA + form then assume there are no such issues and SAVE_EXPRs only + appear via GENERIC foldings. */ + val = get_initialized_tmp_var (val, pre_p, post_p, + gimple_in_ssa_p (cfun)); TREE_OPERAND (*expr_p, 0) = val; SAVE_EXPR_RESOLVED_P (*expr_p) = 1; @@ -6357,6 +6384,7 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0); gimple_asm_set_input (stmt, ASM_INPUT_P (expr)); + gimple_asm_set_inline (stmt, ASM_INLINE_P (expr)); gimplify_seq_add_stmt (pre_p, stmt); } @@ -8168,7 +8196,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, o2 = 0; o2 += bits_to_bytes_round_down (bitpos2); if (maybe_lt (o1, o2) - || (known_eq (o1, 2) + || (known_eq (o1, o2) && maybe_lt (bitpos, bitpos2))) { if (ptr) @@ -9731,9 +9759,26 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); if (!is_gimple_constant (TREE_OPERAND (t, 1))) { + tree type = TREE_TYPE (TREE_OPERAND (t, 0)); TREE_OPERAND (t, 1) = get_initialized_tmp_var (TREE_OPERAND (t, 1), - pre_p, NULL, false); + gimple_seq_empty_p (for_pre_body) + ? pre_p : &for_pre_body, NULL, + false); + /* Reference to pointer conversion is considered useless, + but is significant for firstprivate clause. Force it + here. */ + if (TREE_CODE (type) == POINTER_TYPE + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1))) + == REFERENCE_TYPE)) + { + tree v = create_tmp_var (TYPE_MAIN_VARIANT (type)); + tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, + TREE_OPERAND (t, 1)); + gimplify_and_add (m, gimple_seq_empty_p (for_pre_body) + ? pre_p : &for_pre_body); + TREE_OPERAND (t, 1) = v; + } tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE); OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1); @@ -9745,11 +9790,26 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); if (!is_gimple_constant (TREE_OPERAND (t, 1))) { + tree type = TREE_TYPE (TREE_OPERAND (t, 0)); TREE_OPERAND (t, 1) = get_initialized_tmp_var (TREE_OPERAND (t, 1), gimple_seq_empty_p (for_pre_body) ? pre_p : &for_pre_body, NULL, false); + /* Reference to pointer conversion is considered useless, + but is significant for firstprivate clause. Force it + here. */ + if (TREE_CODE (type) == POINTER_TYPE + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1))) + == REFERENCE_TYPE)) + { + tree v = create_tmp_var (TYPE_MAIN_VARIANT (type)); + tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, + TREE_OPERAND (t, 1)); + gimplify_and_add (m, gimple_seq_empty_p (for_pre_body) + ? pre_p : &for_pre_body); + TREE_OPERAND (t, 1) = v; + } tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE); OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1); @@ -10254,8 +10314,17 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c); else seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c); + push_gimplify_context (); gimplify_assign (decl, t, seq); - } + gimple *bind = NULL; + if (gimplify_ctxp->temps) + { + bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE); + *seq = NULL; + gimplify_seq_add_stmt (seq, bind); + } + pop_gimplify_context (bind); + } } } @@ -10997,9 +11066,36 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p) loadstmt = gimple_build_omp_atomic_load (tmp_load, addr); gimplify_seq_add_stmt (pre_p, loadstmt); - if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue) - != GS_ALL_DONE) - return GS_ERROR; + if (rhs) + { + /* BIT_INSERT_EXPR is not valid for non-integral bitfield + representatives. Use BIT_FIELD_REF on the lhs instead. */ + if (TREE_CODE (rhs) == BIT_INSERT_EXPR + && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load))) + { + tree bitpos = TREE_OPERAND (rhs, 2); + tree op1 = TREE_OPERAND (rhs, 1); + tree bitsize; + tree tmp_store = tmp_load; + if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD) + tmp_store = get_initialized_tmp_var (tmp_load, pre_p, NULL); + if (INTEGRAL_TYPE_P (TREE_TYPE (op1))) + bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1))); + else + bitsize = TYPE_SIZE (TREE_TYPE (op1)); + gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load); + tree t = build2_loc (EXPR_LOCATION (rhs), + MODIFY_EXPR, void_type_node, + build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF, + TREE_TYPE (op1), tmp_store, bitsize, + bitpos), op1); + gimplify_and_add (t, pre_p); + rhs = tmp_store; + } + if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue) + != GS_ALL_DONE) + return GS_ERROR; + } if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ) rhs = tmp_load; diff --git a/contrib/gcc-8.0/gcc/graphite.h b/contrib/gcc-8.0/gcc/graphite.h index 4e0e58c60a..be0a22b389 100644 --- a/contrib/gcc-8.0/gcc/graphite.h +++ b/contrib/gcc-8.0/gcc/graphite.h @@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see #include #include #include +#include +#include typedef struct poly_dr *poly_dr_p; diff --git a/contrib/gcc-8.0/gcc/ipa-cp.c b/contrib/gcc-8.0/gcc/ipa-cp.c index 4f28a55b86..5bd4df0ecb 100644 --- a/contrib/gcc-8.0/gcc/ipa-cp.c +++ b/contrib/gcc-8.0/gcc/ipa-cp.c @@ -820,7 +820,7 @@ build_toporder_info (struct ipa_topo_info *topo) topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count); gcc_checking_assert (topo->stack_top == 0); - topo->nnodes = ipa_reduced_postorder (topo->order, true, true, NULL); + topo->nnodes = ipa_reduced_postorder (topo->order, true, NULL); } /* Free information about strongly connected components and the arrays in @@ -4127,7 +4127,9 @@ intersect_with_plats (struct ipcp_param_lattices *plats, if (aglat->offset - offset == item->offset) { gcc_checking_assert (item->value); - if (values_equal_for_ipcp_p (item->value, aglat->values->value)) + if (aglat->is_single_const () + && values_equal_for_ipcp_p (item->value, + aglat->values->value)) found = true; break; } diff --git a/contrib/gcc-8.0/gcc/ipa-devirt.c b/contrib/gcc-8.0/gcc/ipa-devirt.c index 308b6e6cdd..5b6b130fa3 100644 --- a/contrib/gcc-8.0/gcc/ipa-devirt.c +++ b/contrib/gcc-8.0/gcc/ipa-devirt.c @@ -2615,6 +2615,7 @@ struct polymorphic_call_target_d vec targets; tree decl_warning; int type_warning; + unsigned int n_odr_types; bool complete; bool speculative; }; @@ -2640,6 +2641,7 @@ polymorphic_call_target_hasher::hash (const polymorphic_call_target_d *odr_query hstate.add_hwi (odr_query->type->id); hstate.merge_hash (TYPE_UID (odr_query->context.outer_type)); hstate.add_hwi (odr_query->context.offset); + hstate.add_hwi (odr_query->n_odr_types); if (odr_query->context.speculative_outer_type) { @@ -2670,7 +2672,9 @@ polymorphic_call_target_hasher::equal (const polymorphic_call_target_d *t1, == t2->context.maybe_in_construction && t1->context.maybe_derived_type == t2->context.maybe_derived_type && (t1->context.speculative_maybe_derived_type - == t2->context.speculative_maybe_derived_type)); + == t2->context.speculative_maybe_derived_type) + /* Adding new type may affect outcome of target search. */ + && t1->n_odr_types == t2->n_odr_types); } /* Remove entry in polymorphic call target cache hash. */ @@ -3076,6 +3080,7 @@ possible_polymorphic_call_targets (tree otr_type, key.otr_token = otr_token; key.speculative = speculative; key.context = context; + key.n_odr_types = odr_types.length (); slot = polymorphic_call_target_hash->find_slot (&key, INSERT); if (cache_token) *cache_token = (void *)*slot; @@ -3292,6 +3297,7 @@ possible_polymorphic_call_targets (tree otr_type, (*slot)->targets = nodes; (*slot)->complete = complete; + (*slot)->n_odr_types = odr_types.length (); if (completep) *completep = complete; diff --git a/contrib/gcc-8.0/gcc/ipa-icf-gimple.c b/contrib/gcc-8.0/gcc/ipa-icf-gimple.c index 161080c77b..37b9fe73b0 100644 --- a/contrib/gcc-8.0/gcc/ipa-icf-gimple.c +++ b/contrib/gcc-8.0/gcc/ipa-icf-gimple.c @@ -994,6 +994,9 @@ func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2) if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2)) return false; + if (gimple_asm_inline_p (g1) != gimple_asm_inline_p (g2)) + return false; + if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2)) return false; diff --git a/contrib/gcc-8.0/gcc/ipa-icf.c b/contrib/gcc-8.0/gcc/ipa-icf.c index f974d9f769..21027aa01c 100644 --- a/contrib/gcc-8.0/gcc/ipa-icf.c +++ b/contrib/gcc-8.0/gcc/ipa-icf.c @@ -3160,6 +3160,22 @@ sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls, return true; } +/* Compare function for sorting pairs in do_congruence_step_f. */ + +int +sem_item_optimizer::sort_congruence_split (const void *a_, const void *b_) +{ + const std::pair *a + = (const std::pair *)a_; + const std::pair *b + = (const std::pair *)b_; + if (a->first->id < b->first->id) + return -1; + else if (a->first->id > b->first->id) + return 1; + return 0; +} + /* Tests if a class CLS used as INDEXth splits any congruence classes. Bitmap stack BMSTACK is used for bitmap allocation. */ @@ -3200,13 +3216,20 @@ sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls, } } + auto_vec > to_split; + to_split.reserve_exact (split_map.elements ()); + for (hash_map ::iterator i = split_map.begin (); + i != split_map.end (); ++i) + to_split.safe_push (*i); + to_split.qsort (sort_congruence_split); + traverse_split_pair pair; pair.optimizer = this; pair.cls = cls; splitter_class_removed = false; - split_map.traverse (&pair); + for (unsigned i = 0; i < to_split.length (); ++i) + traverse_congruence_split (to_split[i].first, to_split[i].second, &pair); /* Bitmap clean-up. */ split_map.traverse get (caller)->self_size + growth; badness = - numerator / denominator; @@ -1753,7 +1759,7 @@ inline_small_functions (void) metrics. */ max_count = profile_count::uninitialized (); - ipa_reduced_postorder (order, true, true, NULL); + ipa_reduced_postorder (order, true, NULL); free (order); FOR_EACH_DEFINED_FUNCTION (node) diff --git a/contrib/gcc-8.0/gcc/ipa-polymorphic-call.c b/contrib/gcc-8.0/gcc/ipa-polymorphic-call.c index 13aca94dd0..d5e4a6a6f9 100644 --- a/contrib/gcc-8.0/gcc/ipa-polymorphic-call.c +++ b/contrib/gcc-8.0/gcc/ipa-polymorphic-call.c @@ -995,9 +995,22 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl, { outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (base_pointer))); + cgraph_node *node = cgraph_node::get (current_function_decl); gcc_assert (TREE_CODE (outer_type) == RECORD_TYPE || TREE_CODE (outer_type) == UNION_TYPE); + /* Handle the case we inlined into a thunk. In this case + thunk has THIS pointer of type bar, but it really receives + address to its base type foo which sits in bar at + 0-thunk.fixed_offset. It starts with code that adds + think.fixed_offset to the pointer to compensate for this. + + Because we walked all the way to the begining of thunk, we now + see pointer &bar-thunk.fixed_offset and need to compensate + for it. */ + if (node->thunk.fixed_offset) + offset -= node->thunk.fixed_offset * BITS_PER_UNIT; + /* Dynamic casting has possibly upcasted the type in the hiearchy. In this case outer type is less informative than inner type and we should forget @@ -1005,7 +1018,11 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl, if ((otr_type && !contains_type_p (outer_type, offset, otr_type)) - || !contains_polymorphic_type_p (outer_type)) + || !contains_polymorphic_type_p (outer_type) + /* If we compile thunk with virtual offset, the THIS pointer + is adjusted by unknown value. We can't thus use outer info + at all. */ + || node->thunk.virtual_offset_p) { outer_type = NULL; if (instance) @@ -1030,7 +1047,15 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl, maybe_in_construction = false; } if (instance) - *instance = base_pointer; + { + /* If method is expanded thunk, we need to apply thunk offset + to instance pointer. */ + if (node->thunk.virtual_offset_p + || node->thunk.fixed_offset) + *instance = NULL; + else + *instance = base_pointer; + } return; } /* Non-PODs passed by value are really passed by invisible @@ -1547,6 +1572,9 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance, HOST_WIDE_INT instance_offset = offset; tree instance_outer_type = outer_type; + if (!instance) + return false; + if (otr_type) otr_type = TYPE_MAIN_VARIANT (otr_type); diff --git a/contrib/gcc-8.0/gcc/ipa-prop.c b/contrib/gcc-8.0/gcc/ipa-prop.c index 38441cc49b..7dacdbe2fb 100644 --- a/contrib/gcc-8.0/gcc/ipa-prop.c +++ b/contrib/gcc-8.0/gcc/ipa-prop.c @@ -1569,7 +1569,8 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg, if (TREE_CODE (arg) == SSA_NAME) { tree type_size; - if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))) + if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type))) + || !POINTER_TYPE_P (TREE_TYPE (arg))) return; check_ref = true; arg_base = arg; diff --git a/contrib/gcc-8.0/gcc/ipa-pure-const.c b/contrib/gcc-8.0/gcc/ipa-pure-const.c index a80b684563..d36d1ba9b7 100644 --- a/contrib/gcc-8.0/gcc/ipa-pure-const.c +++ b/contrib/gcc-8.0/gcc/ipa-pure-const.c @@ -1443,7 +1443,7 @@ propagate_pure_const (void) bool remove_p = false; bool has_cdtor; - order_pos = ipa_reduced_postorder (order, true, false, + order_pos = ipa_reduced_postorder (order, true, ignore_edge_for_pure_const); if (dump_file) { @@ -1773,7 +1773,7 @@ propagate_nothrow (void) int i; struct ipa_dfs_info * w_info; - order_pos = ipa_reduced_postorder (order, true, false, + order_pos = ipa_reduced_postorder (order, true, ignore_edge_for_nothrow); if (dump_file) { diff --git a/contrib/gcc-8.0/gcc/ipa-reference.c b/contrib/gcc-8.0/gcc/ipa-reference.c index 6490c03f8d..b9db61697d 100644 --- a/contrib/gcc-8.0/gcc/ipa-reference.c +++ b/contrib/gcc-8.0/gcc/ipa-reference.c @@ -728,7 +728,7 @@ propagate (void) the global information. All the nodes within a cycle will have the same info so we collapse cycles first. Then we can do the propagation in one pass from the leaves to the roots. */ - order_pos = ipa_reduced_postorder (order, true, true, ignore_edge_p); + order_pos = ipa_reduced_postorder (order, true, ignore_edge_p); if (dump_file) ipa_print_order (dump_file, "reduced", order, order_pos); diff --git a/contrib/gcc-8.0/gcc/ipa-utils.c b/contrib/gcc-8.0/gcc/ipa-utils.c index aa586f5feb..106d307939 100644 --- a/contrib/gcc-8.0/gcc/ipa-utils.c +++ b/contrib/gcc-8.0/gcc/ipa-utils.c @@ -63,7 +63,6 @@ struct searchc_env { int order_pos; splay_tree nodes_marked_new; bool reduce; - bool allow_overwritable; int count; }; @@ -105,7 +104,7 @@ searchc (struct searchc_env* env, struct cgraph_node *v, if (w->aux && (avail > AVAIL_INTERPOSABLE - || (env->allow_overwritable && avail == AVAIL_INTERPOSABLE))) + || avail == AVAIL_INTERPOSABLE)) { w_info = (struct ipa_dfs_info *) w->aux; if (w_info->new_node) @@ -162,7 +161,7 @@ searchc (struct searchc_env* env, struct cgraph_node *v, int ipa_reduced_postorder (struct cgraph_node **order, - bool reduce, bool allow_overwritable, + bool reduce, bool (*ignore_edge) (struct cgraph_edge *)) { struct cgraph_node *node; @@ -175,15 +174,13 @@ ipa_reduced_postorder (struct cgraph_node **order, env.nodes_marked_new = splay_tree_new (splay_tree_compare_ints, 0, 0); env.count = 1; env.reduce = reduce; - env.allow_overwritable = allow_overwritable; FOR_EACH_DEFINED_FUNCTION (node) { enum availability avail = node->get_availability (); if (avail > AVAIL_INTERPOSABLE - || (allow_overwritable - && (avail == AVAIL_INTERPOSABLE))) + || avail == AVAIL_INTERPOSABLE) { /* Reuse the info if it is already there. */ struct ipa_dfs_info *info = (struct ipa_dfs_info *) node->aux; @@ -375,6 +372,20 @@ get_base_var (tree t) return t; } +/* Scale function of calls in NODE by ratio ORIG_COUNT/NODE->count. */ + +void +scale_ipa_profile_for_fn (struct cgraph_node *node, profile_count orig_count) +{ + profile_count to = node->count; + profile_count::adjust_for_ipa_scaling (&to, &orig_count); + struct cgraph_edge *e; + + for (e = node->callees; e; e = e->next_callee) + e->count = e->count.apply_scale (to, orig_count); + for (e = node->indirect_calls; e; e = e->next_callee) + e->count = e->count.apply_scale (to, orig_count); +} /* SRC and DST are going to be merged. Take SRC's profile and merge it into DST so it is not going to be lost. Possibly destroy SRC's body on the way @@ -392,6 +403,7 @@ ipa_merge_profiles (struct cgraph_node *dst, if (!src->definition || !dst->definition) return; + if (src->frequency < dst->frequency) src->frequency = dst->frequency; @@ -402,6 +414,10 @@ ipa_merge_profiles (struct cgraph_node *dst, if (src->profile_id && !dst->profile_id) dst->profile_id = src->profile_id; + /* Merging zero profile to dst is no-op. */ + if (src->count.ipa () == profile_count::zero ()) + return; + /* FIXME when we merge in unknown profile, we ought to set counts as unsafe. */ if (!src->count.initialized_p () @@ -412,11 +428,21 @@ ipa_merge_profiles (struct cgraph_node *dst, fprintf (symtab->dump_file, "Merging profiles of %s to %s\n", src->dump_name (), dst->dump_name ()); } + profile_count orig_count = dst->count; + if (dst->count.initialized_p () && dst->count.ipa () == dst->count) dst->count += src->count.ipa (); else dst->count = src->count.ipa (); + /* First handle functions with no gimple body. */ + if (dst->thunk.thunk_p || dst->alias + || src->thunk.thunk_p || src->alias) + { + scale_ipa_profile_for_fn (dst, orig_count); + return; + } + /* This is ugly. We need to get both function bodies into memory. If declaration is merged, we need to duplicate it to be able to load body that is being replaced. This makes symbol table @@ -641,7 +667,10 @@ ipa_merge_profiles (struct cgraph_node *dst, src->release_body (); ipa_update_overall_fn_summary (dst); } - /* TODO: if there is no match, we can scale up. */ + /* We can't update CFG profile, but we can scale IPA profile. CFG + will be scaled according to dst->count after IPA passes. */ + else + scale_ipa_profile_for_fn (dst, orig_count); src->decl = oldsrcdecl; } diff --git a/contrib/gcc-8.0/gcc/ipa-utils.h b/contrib/gcc-8.0/gcc/ipa-utils.h index 1609ac14d7..e247d63fd7 100644 --- a/contrib/gcc-8.0/gcc/ipa-utils.h +++ b/contrib/gcc-8.0/gcc/ipa-utils.h @@ -36,7 +36,7 @@ struct ipa_dfs_info { /* In ipa-utils.c */ void ipa_print_order (FILE*, const char *, struct cgraph_node**, int); -int ipa_reduced_postorder (struct cgraph_node **, bool, bool, +int ipa_reduced_postorder (struct cgraph_node **, bool, bool (*ignore_edge) (struct cgraph_edge *)); void ipa_free_postorder_info (void); vec ipa_get_nodes_in_cycle (struct cgraph_node *); diff --git a/contrib/gcc-8.0/gcc/ipa-visibility.c b/contrib/gcc-8.0/gcc/ipa-visibility.c index a82852b3ce..1e89255e8f 100644 --- a/contrib/gcc-8.0/gcc/ipa-visibility.c +++ b/contrib/gcc-8.0/gcc/ipa-visibility.c @@ -543,7 +543,8 @@ localize_node (bool whole_program, symtab_node *node) symbols. In this case we can privatize all hidden symbol but we need to keep non-hidden exported. */ if (node->same_comdat_group - && node->resolution == LDPR_PREVAILING_DEF_IRONLY) + && (node->resolution == LDPR_PREVAILING_DEF_IRONLY + || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)) { symtab_node *next; for (next = node->same_comdat_group; diff --git a/contrib/gcc-8.0/gcc/ipa.c b/contrib/gcc-8.0/gcc/ipa.c index 9330de59c7..2e6621ccc8 100644 --- a/contrib/gcc-8.0/gcc/ipa.c +++ b/contrib/gcc-8.0/gcc/ipa.c @@ -854,7 +854,9 @@ ipa_discover_readonly_nonaddressable_vars (void) be produced. */ static void -cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final) +cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final, + tree optimization, + tree target) { static int counter = 0; char which_buf[16]; @@ -885,6 +887,8 @@ cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final) TREE_STATIC (decl) = 1; TREE_USED (decl) = 1; + DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl) = optimization; + DECL_FUNCTION_SPECIFIC_TARGET (decl) = target; DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; @@ -949,7 +953,7 @@ cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final) void cgraph_build_static_cdtor (char which, tree body, int priority) { - cgraph_build_static_cdtor_1 (which, body, priority, false); + cgraph_build_static_cdtor_1 (which, body, priority, false, NULL, NULL); } /* When target does not have ctors and dtors, we call all constructor @@ -1031,7 +1035,9 @@ build_cdtor (bool ctor_p, const vec &cdtors) gcc_assert (body != NULL_TREE); /* Generate a function to call all the function of like priority. */ - cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true); + cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true, + DECL_FUNCTION_SPECIFIC_OPTIMIZATION (cdtors[0]), + DECL_FUNCTION_SPECIFIC_TARGET (cdtors[0])); } } diff --git a/contrib/gcc-8.0/gcc/langhooks.c b/contrib/gcc-8.0/gcc/langhooks.c index 3cd790105b..b24c87a8a8 100644 --- a/contrib/gcc-8.0/gcc/langhooks.c +++ b/contrib/gcc-8.0/gcc/langhooks.c @@ -368,7 +368,7 @@ lhd_print_error_function (diagnostic_context *context, const char *file, { if (diagnostic_last_function_changed (context, diagnostic)) { - const char *old_prefix = context->printer->prefix; + char *old_prefix = pp_take_prefix (context->printer); tree abstract_origin = diagnostic_abstract_origin (diagnostic); char *new_prefix = (file && abstract_origin == NULL) ? file_name_as_prefix (context, file) : NULL; diff --git a/contrib/gcc-8.0/gcc/lower-subreg.c b/contrib/gcc-8.0/gcc/lower-subreg.c index 32e70dcbd1..72818b8255 100644 --- a/contrib/gcc-8.0/gcc/lower-subreg.c +++ b/contrib/gcc-8.0/gcc/lower-subreg.c @@ -497,7 +497,16 @@ find_decomposable_subregs (rtx *loc, enum classify_move_insn *pcmi) were the same number and size of pieces. Hopefully this doesn't happen much. */ - if (outer_words == 1 && inner_words > 1) + if (outer_words == 1 + && inner_words > 1 + /* Don't allow to decompose floating point subregs of + multi-word pseudos if the floating point mode does + not have word size, because otherwise we'd generate + a subreg with that floating mode from a different + sized integral pseudo which is not allowed by + validate_subreg. */ + && (!FLOAT_MODE_P (GET_MODE (x)) + || outer_size == UNITS_PER_WORD)) { bitmap_set_bit (decomposable_context, regno); iter.skip_subrtxes (); diff --git a/contrib/gcc-8.0/gcc/lra.c b/contrib/gcc-8.0/gcc/lra.c index b410b90f12..44af904787 100644 --- a/contrib/gcc-8.0/gcc/lra.c +++ b/contrib/gcc-8.0/gcc/lra.c @@ -1692,10 +1692,12 @@ lra_rtx_hash (rtx x) case SCRATCH: case CONST_DOUBLE: - case CONST_INT: case CONST_VECTOR: return val; + case CONST_INT: + return val + UINTVAL (x); + default: break; } diff --git a/contrib/gcc-8.0/gcc/lto-cgraph.c b/contrib/gcc-8.0/gcc/lto-cgraph.c index dcd5391012..305f22bd7e 100644 --- a/contrib/gcc-8.0/gcc/lto-cgraph.c +++ b/contrib/gcc-8.0/gcc/lto-cgraph.c @@ -546,7 +546,11 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, streamer_write_bitpack (&bp); streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1); - if (node->thunk.thunk_p) + /* Stream thunk info always because we use it in + ipa_polymorphic_call_context::ipa_polymorphic_call_context + to properly interpret THIS pointers for thunks that has been converted + to Gimple. */ + if (node->definition) { streamer_write_uhwi_stream (ob->main_stream, @@ -1257,6 +1261,8 @@ input_node (struct lto_file_decl_data *file_data, of ipa passes is done. Alays forcingly create a fresh node. */ node = symtab->create_empty (); node->decl = fn_decl; + if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl))) + node->ifunc_resolver = 1; node->register_symbol (); } @@ -1315,7 +1321,7 @@ input_node (struct lto_file_decl_data *file_data, if (section) node->set_section_for_node (section); - if (node->thunk.thunk_p) + if (node->definition) { int type = streamer_read_uhwi (ib); HOST_WIDE_INT fixed_offset = streamer_read_uhwi (ib); diff --git a/contrib/gcc-8.0/gcc/lto-opts.c b/contrib/gcc-8.0/gcc/lto-opts.c index ea336ad99b..527045f74a 100644 --- a/contrib/gcc-8.0/gcc/lto-opts.c +++ b/contrib/gcc-8.0/gcc/lto-opts.c @@ -78,6 +78,21 @@ lto_write_options (void) && !global_options.x_flag_openacc) append_to_collect_gcc_options (&temporary_obstack, &first_p, "-fno-openacc"); + /* Append PIC/PIE mode because its default depends on target and it is + subject of merging in lto-wrapper. */ + if (!global_options_set.x_flag_pic && !global_options_set.x_flag_pie) + { + append_to_collect_gcc_options (&temporary_obstack, &first_p, + global_options.x_flag_pic == 2 + ? "-fPIC" + : global_options.x_flag_pic == 1 + ? "-fpic" + : global_options.x_flag_pie == 2 + ? "-fPIE" + : global_options.x_flag_pie == 1 + ? "-fpie" + : "-fno-pie"); + } /* Append options from target hook and store them to offload_lto section. */ if (lto_stream_offload_p) diff --git a/contrib/gcc-8.0/gcc/lto-streamer-out.c b/contrib/gcc-8.0/gcc/lto-streamer-out.c index 1d2ab9757f..6962e9e25d 100644 --- a/contrib/gcc-8.0/gcc/lto-streamer-out.c +++ b/contrib/gcc-8.0/gcc/lto-streamer-out.c @@ -299,7 +299,6 @@ lto_is_streamable (tree expr) name version in lto_output_tree_ref (see output_ssa_names). */ return !is_lang_specific (expr) && code != SSA_NAME - && code != CALL_EXPR && code != LANG_TYPE && code != MODIFY_EXPR && code != INIT_EXPR diff --git a/contrib/gcc-8.0/gcc/lto-streamer.h b/contrib/gcc-8.0/gcc/lto-streamer.h index d5873f7dab..11d9888daf 100644 --- a/contrib/gcc-8.0/gcc/lto-streamer.h +++ b/contrib/gcc-8.0/gcc/lto-streamer.h @@ -121,7 +121,7 @@ along with GCC; see the file COPYING3. If not see form followed by the data for the string. */ #define LTO_major_version 7 -#define LTO_minor_version 0 +#define LTO_minor_version 1 typedef unsigned char lto_decl_flags_t; diff --git a/contrib/gcc-8.0/gcc/lto-wrapper.c b/contrib/gcc-8.0/gcc/lto-wrapper.c index f1f059cbfc..7a3f93ab2a 100644 --- a/contrib/gcc-8.0/gcc/lto-wrapper.c +++ b/contrib/gcc-8.0/gcc/lto-wrapper.c @@ -65,6 +65,7 @@ static enum lto_mode_d lto_mode = LTO_MODE_NONE; static char *ltrans_output_file; static char *flto_out; static unsigned int nr; +static int *ltrans_priorities; static char **input_names; static char **output_names; static char **offload_names; @@ -407,6 +408,11 @@ merge_and_complain (struct cl_decoded_option **decoded_options, It is a common mistake to mix few -fPIC compiled objects into otherwise non-PIC code. We do not want to build everything with PIC then. + Similarly we merge PIE options, however in addition we keep + -fPIC + -fPIE = -fPIE + -fpic + -fPIE = -fpie + -fPIC/-fpic + -fpie = -fpie + It would be good to warn on mismatches, but it is bit hard to do as we do not know what nothing translates to. */ @@ -414,11 +420,38 @@ merge_and_complain (struct cl_decoded_option **decoded_options, if ((*decoded_options)[j].opt_index == OPT_fPIC || (*decoded_options)[j].opt_index == OPT_fpic) { - if (!pic_option - || (pic_option->value > 0) != ((*decoded_options)[j].value > 0)) - remove_option (decoded_options, j, decoded_options_count); - else if (pic_option->opt_index == OPT_fPIC - && (*decoded_options)[j].opt_index == OPT_fpic) + /* -fno-pic in one unit implies -fno-pic everywhere. */ + if ((*decoded_options)[j].value == 0) + j++; + /* If we have no pic option or merge in -fno-pic, we still may turn + existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */ + else if ((pic_option && pic_option->value == 0) + || !pic_option) + { + if (pie_option) + { + bool big = (*decoded_options)[j].opt_index == OPT_fPIC + && pie_option->opt_index == OPT_fPIE; + (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie; + if (pie_option->value) + (*decoded_options)[j].canonical_option[0] = big ? "-fPIE" : "-fpie"; + else + (*decoded_options)[j].canonical_option[0] = big ? "-fno-pie" : "-fno-pie"; + (*decoded_options)[j].value = pie_option->value; + j++; + } + else if (pic_option) + { + (*decoded_options)[j] = *pic_option; + j++; + } + /* We do not know if target defaults to pic or not, so just remove + option if it is missing in one unit but enabled in other. */ + else + remove_option (decoded_options, j, decoded_options_count); + } + else if (pic_option->opt_index == OPT_fpic + && (*decoded_options)[j].opt_index == OPT_fPIC) { (*decoded_options)[j] = *pic_option; j++; @@ -429,11 +462,42 @@ merge_and_complain (struct cl_decoded_option **decoded_options, else if ((*decoded_options)[j].opt_index == OPT_fPIE || (*decoded_options)[j].opt_index == OPT_fpie) { - if (!pie_option - || pie_option->value != (*decoded_options)[j].value) - remove_option (decoded_options, j, decoded_options_count); - else if (pie_option->opt_index == OPT_fPIE - && (*decoded_options)[j].opt_index == OPT_fpie) + /* -fno-pie in one unit implies -fno-pie everywhere. */ + if ((*decoded_options)[j].value == 0) + j++; + /* If we have no pie option or merge in -fno-pie, we still preserve + PIE/pie if pic/PIC is present. */ + else if ((pie_option && pie_option->value == 0) + || !pie_option) + { + /* If -fPIC/-fpic is given, merge it with -fPIE/-fpie. */ + if (pic_option) + { + if (pic_option->opt_index == OPT_fpic + && (*decoded_options)[j].opt_index == OPT_fPIE) + { + (*decoded_options)[j].opt_index = OPT_fpie; + (*decoded_options)[j].canonical_option[0] + = pic_option->value ? "-fpie" : "-fno-pie"; + } + else if (!pic_option->value) + (*decoded_options)[j].canonical_option[0] = "-fno-pie"; + (*decoded_options)[j].value = pic_option->value; + j++; + } + else if (pie_option) + { + (*decoded_options)[j] = *pie_option; + j++; + } + /* Because we always append pic/PIE options this code path should + not happen unless the LTO object was built by old lto1 which + did not contain that logic yet. */ + else + remove_option (decoded_options, j, decoded_options_count); + } + else if (pie_option->opt_index == OPT_fpie + && (*decoded_options)[j].opt_index == OPT_fPIE) { (*decoded_options)[j] = *pie_option; j++; @@ -1018,6 +1082,13 @@ debug_objcopy (const char *infile) return outfile; } +/* Helper for qsort: compare priorities for parallel compilation. */ + +int +cmp_priority (const void *a, const void *b) +{ + return *((const int *)b)-*((const int *)a); +} /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */ @@ -1477,6 +1548,7 @@ cont1: FILE *stream = fopen (ltrans_output_file, "r"); FILE *mstream = NULL; struct obstack env_obstack; + int priority; if (!stream) fatal_error (input_location, "fopen: %s: %m", ltrans_output_file); @@ -1492,6 +1564,14 @@ cont1: size_t len; buf = input_name; + if (fscanf (stream, "%i\n", &priority) != 1) + { + if (!feof (stream)) + fatal_error (input_location, + "Corrupted ltrans output file %s", + ltrans_output_file); + break; + } cont: if (!fgets (buf, piece, stream)) break; @@ -1508,8 +1588,12 @@ cont: output_name = &input_name[1]; nr++; + ltrans_priorities + = (int *)xrealloc (ltrans_priorities, nr * sizeof (int) * 2); input_names = (char **)xrealloc (input_names, nr * sizeof (char *)); output_names = (char **)xrealloc (output_names, nr * sizeof (char *)); + ltrans_priorities[(nr-1)*2] = priority; + ltrans_priorities[(nr-1)*2+1] = nr-1; input_names[nr-1] = input_name; output_names[nr-1] = output_name; } @@ -1521,6 +1605,7 @@ cont: { makefile = make_temp_file (".mk"); mstream = fopen (makefile, "w"); + qsort (ltrans_priorities, nr, sizeof (int) * 2, cmp_priority); } /* Execute the LTRANS stage for each input file (or prepare a @@ -1586,7 +1671,10 @@ cont: fprintf (mstream, "all:"); for (i = 0; i < nr; ++i) - fprintf (mstream, " \\\n\t%s", output_names[i]); + { + int j = ltrans_priorities[i*2 + 1]; + fprintf (mstream, " \\\n\t%s", output_names[j]); + } fprintf (mstream, "\n"); fclose (mstream); if (!jobserver) @@ -1630,6 +1718,7 @@ cont: free (input_names[i]); } nr = 0; + free (ltrans_priorities); free (output_names); free (input_names); free (list_option_full); diff --git a/contrib/gcc-8.0/gcc/lto/lto-partition.c b/contrib/gcc-8.0/gcc/lto/lto-partition.c index 60daafdf37..bf88d8a4e6 100644 --- a/contrib/gcc-8.0/gcc/lto/lto-partition.c +++ b/contrib/gcc-8.0/gcc/lto/lto-partition.c @@ -35,12 +35,31 @@ along with GCC; see the file COPYING3. If not see #include "ipa-prop.h" #include "ipa-fnsummary.h" #include "lto-partition.h" +#include "sreal.h" vec ltrans_partitions; static void add_symbol_to_partition (ltrans_partition part, symtab_node *node); +/* Helper for qsort; compare partitions and return one with smaller order. */ + +static int +cmp_partitions_order (const void *a, const void *b) +{ + const struct ltrans_partition_def *pa + = *(struct ltrans_partition_def *const *)a; + const struct ltrans_partition_def *pb + = *(struct ltrans_partition_def *const *)b; + int ordera = -1, orderb = -1; + + if (lto_symtab_encoder_size (pa->encoder)) + ordera = lto_symtab_encoder_deref (pa->encoder, 0)->order; + if (lto_symtab_encoder_size (pb->encoder)) + orderb = lto_symtab_encoder_deref (pb->encoder, 0)->order; + return orderb - ordera; +} + /* Create new partition with name NAME. */ static ltrans_partition @@ -152,8 +171,8 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node) if (cgraph_node *cnode = dyn_cast (node)) { struct cgraph_edge *e; - if (!node->alias) - part->insns += ipa_fn_summaries->get (cnode)->self_size; + if (!node->alias && c == SYMBOL_PARTITION) + part->insns += ipa_fn_summaries->get (cnode)->size; /* Add all inline clones and callees that are duplicated. */ for (e = cnode->callees; e; e = e->next_callee) @@ -276,8 +295,9 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes) delete partition->initializers_visited; partition->initializers_visited = NULL; - if (!node->alias && (cnode = dyn_cast (node))) - partition->insns -= ipa_fn_summaries->get (cnode)->self_size; + if (!node->alias && (cnode = dyn_cast (node)) + && node->get_partitioning_class () == SYMBOL_PARTITION) + partition->insns -= ipa_fn_summaries->get (cnode)->size; lto_symtab_encoder_delete_node (partition->encoder, node); node->aux = (void *)((size_t)node->aux - 1); } @@ -332,6 +352,9 @@ lto_1_to_1_map (void) if (!npartitions) new_partition ("empty"); + /* Order partitions by order of symbols because they are linked into binary + that way. */ + ltrans_partitions.qsort (cmp_partitions_order); } /* Maximal partitioning. Put every new symbol into new partition if possible. */ @@ -408,6 +431,39 @@ add_sorted_nodes (vec &next_nodes, ltrans_partition partition) add_symbol_to_partition (partition, node); } +/* Return true if we should account reference from N1 to N2 in cost + of partition boundary. */ + +bool +account_reference_p (symtab_node *n1, symtab_node *n2) +{ + if (cgraph_node *cnode = dyn_cast (n1)) + n1 = cnode; + /* Do not account references from aliases - they are never split across + partitions. */ + if (n1->alias) + return false; + /* Do not account recursion - the code below will handle it incorrectly + otherwise. Do not account references to external symbols: they will + never become local. Finally do not account references to duplicated + symbols: they will be always local. */ + if (n1 == n2 + || !n2->definition + || n2->get_partitioning_class () != SYMBOL_PARTITION) + return false; + /* If referring node is external symbol do not account it to boundary + cost. Those are added into units only to enable possible constant + folding and devirtulization. + + Here we do not know if it will ever be added to some partition + (this is decided by compute_ltrans_boundary) and second it is not + that likely that constant folding will actually use the reference. */ + if (contained_in_symbol (n1) + ->get_partitioning_class () == SYMBOL_EXTERNAL) + return false; + return true; +} + /* Group cgraph nodes into equally-sized partitions. @@ -450,35 +506,33 @@ add_sorted_nodes (vec &next_nodes, ltrans_partition partition) void lto_balanced_map (int n_lto_partitions, int max_partition_size) { - int n_nodes = 0; int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0; - struct cgraph_node **order = XNEWVEC (cgraph_node *, symtab->cgraph_max_uid); + auto_vec order (symtab->cgraph_count); auto_vec noreorder; auto_vec varpool_order; - int i; struct cgraph_node *node; - int original_total_size, total_size = 0, best_total_size = 0; - int partition_size; + int64_t original_total_size, total_size = 0; + int64_t partition_size; ltrans_partition partition; int last_visited_node = 0; varpool_node *vnode; - int cost = 0, internal = 0; - int best_n_nodes = 0, best_i = 0, best_cost = - INT_MAX, best_internal = 0; + int64_t cost = 0, internal = 0; + unsigned int best_n_nodes = 0, best_i = 0; + int64_t best_cost = -1, best_internal = 0, best_size = 0; int npartitions; int current_order = -1; int noreorder_pos = 0; FOR_EACH_VARIABLE (vnode) gcc_assert (!vnode->aux); - + FOR_EACH_DEFINED_FUNCTION (node) if (node->get_partitioning_class () == SYMBOL_PARTITION) { if (node->no_reorder) noreorder.safe_push (node); else - order[n_nodes++] = node; + order.safe_push (node); if (!node->alias) total_size += ipa_fn_summaries->get (node)->size; } @@ -490,15 +544,15 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) unit tends to import a lot of global trees defined there. We should get better about minimizing the function bounday, but until that things works smoother if we order in source order. */ - qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp); + order.qsort (node_cmp); noreorder.qsort (node_cmp); if (symtab->dump_file) { - for(i = 0; i < n_nodes; i++) + for (unsigned i = 0; i < order.length (); i++) fprintf (symtab->dump_file, "Balanced map symbol order:%s:%u\n", order[i]->name (), order[i]->tp_first_run); - for(i = 0; i < (int)noreorder.length(); i++) + for (unsigned i = 0; i < noreorder.length (); i++) fprintf (symtab->dump_file, "Balanced map symbol no_reorder:%s:%u\n", noreorder[i]->name (), noreorder[i]->tp_first_run); } @@ -513,7 +567,8 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) /* Compute partition size and create the first partition. */ if (PARAM_VALUE (MIN_PARTITION_SIZE) > max_partition_size) - fatal_error (input_location, "min partition size cannot be greater than max partition size"); + fatal_error (input_location, "min partition size cannot be greater " + "than max partition size"); partition_size = total_size / n_lto_partitions; if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE)) @@ -521,12 +576,13 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) npartitions = 1; partition = new_partition (""); if (symtab->dump_file) - fprintf (symtab->dump_file, "Total unit size: %i, partition size: %i\n", + fprintf (symtab->dump_file, "Total unit size: %" PRId64 + ", partition size: %" PRId64 "\n", total_size, partition_size); auto_vec next_nodes; - for (i = 0; i < n_nodes; i++) + for (unsigned i = 0; i < order.length (); i++) { if (symbol_partitioned_p (order[i])) continue; @@ -540,17 +596,11 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) next_nodes.safe_push (varpool_order[varpool_pos++]); while (noreorder_pos < (int)noreorder.length () && noreorder[noreorder_pos]->order < current_order) - { - if (!noreorder[noreorder_pos]->alias) - total_size -= ipa_fn_summaries->get (noreorder[noreorder_pos])->size; - next_nodes.safe_push (noreorder[noreorder_pos++]); - } + next_nodes.safe_push (noreorder[noreorder_pos++]); add_sorted_nodes (next_nodes, partition); if (!symbol_partitioned_p (order[i])) add_symbol_to_partition (partition, order[i]); - if (!order[i]->alias) - total_size -= ipa_fn_summaries->get (order[i])->size; /* Once we added a new node to the partition, we also want to add @@ -567,7 +617,6 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) it and thus we need to subtract it from COST. */ while (last_visited_node < lto_symtab_encoder_size (partition->encoder)) { - symtab_node *refs_node; int j; struct ipa_ref *ref = NULL; symtab_node *snode = lto_symtab_encoder_deref (partition->encoder, @@ -577,7 +626,6 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) { struct cgraph_edge *edge; - refs_node = node; last_visited_node++; @@ -585,7 +633,9 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) /* Compute boundary cost of callgraph edges. */ for (edge = node->callees; edge; edge = edge->next_callee) - if (edge->callee->definition) + /* Inline edges will always end up local. */ + if (edge->inline_failed + && account_reference_p (node, edge->callee)) { int edge_cost = edge->frequency (); int index; @@ -602,6 +652,8 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) cost += edge_cost; } for (edge = node->callers; edge; edge = edge->next_caller) + if (edge->inline_failed + && account_reference_p (edge->caller, node)) { int edge_cost = edge->frequency (); int index; @@ -614,27 +666,24 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) edge->caller); if (index != LCC_NOT_FOUND && index < last_visited_node - 1) - cost -= edge_cost; + cost -= edge_cost, internal += edge_cost; else cost += edge_cost; } } else - { - refs_node = snode; - last_visited_node++; - } + last_visited_node++; /* Compute boundary cost of IPA REF edges and at the same time look into variables referenced from current partition and try to add them. */ - for (j = 0; refs_node->iterate_reference (j, ref); j++) - if (is_a (ref->referred)) + for (j = 0; snode->iterate_reference (j, ref); j++) + if (!account_reference_p (snode, ref->referred)) + ; + else if (is_a (ref->referred)) { int index; vnode = dyn_cast (ref->referred); - if (!vnode->definition) - continue; if (!symbol_partitioned_p (vnode) && !vnode->no_reorder && vnode->get_partitioning_class () == SYMBOL_PARTITION) @@ -652,8 +701,6 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) int index; node = dyn_cast (ref->referred); - if (!node->definition) - continue; index = lto_symtab_encoder_lookup (partition->encoder, node); if (index != LCC_NOT_FOUND @@ -662,8 +709,10 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) else cost++; } - for (j = 0; refs_node->iterate_referring (j, ref); j++) - if (is_a (ref->referring)) + for (j = 0; snode->iterate_referring (j, ref); j++) + if (!account_reference_p (ref->referring, snode)) + ; + else if (is_a (ref->referring)) { int index; @@ -682,7 +731,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) vnode); if (index != LCC_NOT_FOUND && index < last_visited_node - 1) - cost--; + cost--, internal++; else cost++; } @@ -696,36 +745,41 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) node); if (index != LCC_NOT_FOUND && index < last_visited_node - 1) - cost--; + cost--, internal++; else cost++; } } - /* If the partition is large enough, start looking for smallest boundary cost. */ - if (partition->insns < partition_size * 3 / 4 - || best_cost == INT_MAX - || ((!cost - || (best_internal * (HOST_WIDE_INT) cost - > (internal * (HOST_WIDE_INT)best_cost))) - && partition->insns < partition_size * 5 / 4)) + gcc_assert (cost >= 0 && internal >= 0); + + /* If the partition is large enough, start looking for smallest boundary cost. + If partition still seems too small (less than 7/8 of target weight) accept + any cost. If partition has right size, optimize for highest internal/cost. + Later we stop building partition if its size is 9/8 of the target wight. */ + if (partition->insns < partition_size * 7 / 8 + || best_cost == -1 + || (!cost + || ((sreal)best_internal * (sreal) cost + < ((sreal) internal * (sreal)best_cost)))) { best_cost = cost; best_internal = internal; + best_size = partition->insns; best_i = i; best_n_nodes = lto_symtab_encoder_size (partition->encoder); - best_total_size = total_size; best_varpool_pos = varpool_pos; } if (symtab->dump_file) - fprintf (symtab->dump_file, "Step %i: added %s/%i, size %i, cost %i/%i " - "best %i/%i, step %i\n", i, + fprintf (symtab->dump_file, "Step %i: added %s/%i, size %i, " + "cost %" PRId64 "/%" PRId64 " " + "best %" PRId64 "/%" PRId64", step %i\n", i, order[i]->name (), order[i]->order, partition->insns, cost, internal, best_cost, best_internal, best_i); /* Partition is too large, unwind into step when best cost was reached and start new partition. */ - if (partition->insns > 2 * partition_size + if (partition->insns > 9 * partition_size / 8 || partition->insns > max_partition_size) { if (best_i != i) @@ -736,21 +790,26 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) undo_partition (partition, best_n_nodes); varpool_pos = best_varpool_pos; } + gcc_assert (best_size == partition->insns); i = best_i; + if (symtab->dump_file) + fprintf (symtab->dump_file, + "Partition insns: %i (want %" PRId64 ")\n", + partition->insns, partition_size); /* When we are finished, avoid creating empty partition. */ - while (i < n_nodes - 1 && symbol_partitioned_p (order[i + 1])) + while (i < order.length () - 1 && symbol_partitioned_p (order[i + 1])) i++; - if (i == n_nodes - 1) + if (i == order.length () - 1) break; + total_size -= partition->insns; partition = new_partition (""); last_visited_node = 0; - total_size = best_total_size; cost = 0; if (symtab->dump_file) fprintf (symtab->dump_file, "New partition\n"); best_n_nodes = 0; - best_cost = INT_MAX; + best_cost = -1; /* Since the size of partitions is just approximate, update the size after we finished current one. */ @@ -760,6 +819,10 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) /* Watch for overflow. */ partition_size = INT_MAX / 16; + if (symtab->dump_file) + fprintf (symtab->dump_file, + "Total size: %" PRId64 " partition_size: %" PRId64 "\n", + total_size, partition_size); if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE)) partition_size = PARAM_VALUE (MIN_PARTITION_SIZE); npartitions ++; @@ -779,10 +842,11 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) next_nodes.safe_push (varpool_order[varpool_pos++]); while (noreorder_pos < (int)noreorder.length ()) next_nodes.safe_push (noreorder[noreorder_pos++]); + /* For one partition the cost of boundary should be 0 unless we added final + symbols here (these are not accounted) or we have accounting bug. */ + gcc_assert (next_nodes.length () || npartitions != 1 || !best_cost || best_cost == -1); add_sorted_nodes (next_nodes, partition); - free (order); - if (symtab->dump_file) { fprintf (symtab->dump_file, "\nPartition sizes:\n"); @@ -793,7 +857,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) ltrans_partition p = ltrans_partitions[i]; fprintf (symtab->dump_file, "partition %d contains %d (%2.2f%%)" " symbols and %d (%2.2f%%) insns\n", i, p->symbols, - 100.0 * p->symbols / n_nodes, p->insns, + 100.0 * p->symbols / order.length (), p->insns, 100.0 * p->insns / original_total_size); } diff --git a/contrib/gcc-8.0/gcc/lto/lto-symtab.c b/contrib/gcc-8.0/gcc/lto/lto-symtab.c index 3663ab7a9b..cec74894c0 100644 --- a/contrib/gcc-8.0/gcc/lto/lto-symtab.c +++ b/contrib/gcc-8.0/gcc/lto/lto-symtab.c @@ -388,8 +388,9 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry) int a[]={1,2,3}; here the first declaration is COMMON and sizeof(a) == sizeof (int). */ - else if (TREE_CODE (type) == ARRAY_TYPE) - return (TYPE_SIZE (decl) == TYPE_SIZE (TREE_TYPE (type))); + else if (TREE_CODE (type) != ARRAY_TYPE + || (TYPE_SIZE (type) != TYPE_SIZE (TREE_TYPE (type)))) + return false; } return true; diff --git a/contrib/gcc-8.0/gcc/lto/lto.c b/contrib/gcc-8.0/gcc/lto/lto.c index 1c55f3f691..d2ccaf6768 100644 --- a/contrib/gcc-8.0/gcc/lto/lto.c +++ b/contrib/gcc-8.0/gcc/lto/lto.c @@ -2327,38 +2327,6 @@ free_section_data (struct lto_file_decl_data *file_data ATTRIBUTE_UNUSED, static lto_file *current_lto_file; -/* Helper for qsort; compare partitions and return one with smaller size. - We sort from greatest to smallest so parallel build doesn't stale on the - longest compilation being executed too late. */ - -static int -cmp_partitions_size (const void *a, const void *b) -{ - const struct ltrans_partition_def *pa - = *(struct ltrans_partition_def *const *)a; - const struct ltrans_partition_def *pb - = *(struct ltrans_partition_def *const *)b; - return pb->insns - pa->insns; -} - -/* Helper for qsort; compare partitions and return one with smaller order. */ - -static int -cmp_partitions_order (const void *a, const void *b) -{ - const struct ltrans_partition_def *pa - = *(struct ltrans_partition_def *const *)a; - const struct ltrans_partition_def *pb - = *(struct ltrans_partition_def *const *)b; - int ordera = -1, orderb = -1; - - if (lto_symtab_encoder_size (pa->encoder)) - ordera = lto_symtab_encoder_deref (pa->encoder, 0)->order; - if (lto_symtab_encoder_size (pb->encoder)) - orderb = lto_symtab_encoder_deref (pb->encoder, 0)->order; - return orderb - ordera; -} - /* Actually stream out ENCODER into TEMP_FILENAME. */ static void @@ -2468,7 +2436,8 @@ lto_wpa_write_files (void) ltrans_partition part; FILE *ltrans_output_list_stream; char *temp_filename; - vec temp_filenames = vNULL; + auto_vec temp_filenames; + auto_vec temp_priority; size_t blen; /* Open the LTRANS output list. */ @@ -2496,15 +2465,6 @@ lto_wpa_write_files (void) n_sets = ltrans_partitions.length (); - /* Sort partitions by size so small ones are compiled last. - FIXME: Even when not reordering we may want to output one list for parallel make - and other for final link command. */ - - if (!flag_profile_reorder_functions || !flag_profile_use) - ltrans_partitions.qsort (flag_toplevel_reorder - ? cmp_partitions_size - : cmp_partitions_order); - for (i = 0; i < n_sets; i++) { ltrans_partition part = ltrans_partitions[i]; @@ -2556,6 +2516,7 @@ lto_wpa_write_files (void) part->encoder = NULL; + temp_priority.safe_push (part->insns); temp_filenames.safe_push (xstrdup (temp_filename)); } ltrans_output_list_stream = fopen (ltrans_output_list, "w"); @@ -2565,13 +2526,13 @@ lto_wpa_write_files (void) for (i = 0; i < n_sets; i++) { unsigned int len = strlen (temp_filenames[i]); - if (fwrite (temp_filenames[i], 1, len, ltrans_output_list_stream) < len + if (fprintf (ltrans_output_list_stream, "%i\n", temp_priority[i]) < 0 + || fwrite (temp_filenames[i], 1, len, ltrans_output_list_stream) < len || fwrite ("\n", 1, 1, ltrans_output_list_stream) < 1) fatal_error (input_location, "writing to LTRANS output list %s: %m", ltrans_output_list); free (temp_filenames[i]); } - temp_filenames.release(); lto_stats.num_output_files += n_sets; diff --git a/contrib/gcc-8.0/gcc/match.pd b/contrib/gcc-8.0/gcc/match.pd index 0de4432d92..d6ac4389ee 100644 --- a/contrib/gcc-8.0/gcc/match.pd +++ b/contrib/gcc-8.0/gcc/match.pd @@ -1417,6 +1417,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (op:c (plus:c@2 @0 @1) @1) (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)) + && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)) && (CONSTANT_CLASS_P (@0) || single_use (@2))) (op @0 { build_zero_cst (TREE_TYPE (@0)); })))) /* For equality, this is also true with wrapping overflow. */ @@ -1450,14 +1451,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (op @1 { build_zero_cst (TREE_TYPE (@1)); })))) /* Transform: - * (X / Y) == 0 -> X < Y if X, Y are unsigned. - * (X / Y) != 0 -> X >= Y, if X, Y are unsigned. - */ + (X / Y) == 0 -> X < Y if X, Y are unsigned. + (X / Y) != 0 -> X >= Y, if X, Y are unsigned. */ (for cmp (eq ne) ocmp (lt ge) (simplify (cmp (trunc_div @0 @1) integer_zerop) (if (TYPE_UNSIGNED (TREE_TYPE (@0)) + /* Complex ==/!= is allowed, but not =. */ + && TREE_CODE (TREE_TYPE (@0)) != COMPLEX_TYPE && (VECTOR_TYPE_P (type) || !VECTOR_TYPE_P (TREE_TYPE (@0)))) (ocmp @0 @1)))) @@ -1589,14 +1591,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (ptr_difference_const (@0, @1, &diff)) { build_int_cst_type (type, diff); })))) (simplify - (pointer_diff (convert?@2 ADDR_EXPR@0) (convert?@3 @1)) + (pointer_diff (convert?@2 ADDR_EXPR@0) (convert1?@3 @1)) (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0)) && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1))) (with { poly_int64 diff; } (if (ptr_difference_const (@0, @1, &diff)) { build_int_cst_type (type, diff); })))) (simplify - (pointer_diff (convert?@2 @0) (convert?@3 ADDR_EXPR@1)) + (pointer_diff (convert?@2 @0) (convert1?@3 ADDR_EXPR@1)) (if (tree_nop_conversion_p (TREE_TYPE(@2), TREE_TYPE (@0)) && tree_nop_conversion_p (TREE_TYPE(@3), TREE_TYPE (@1))) (with { poly_int64 diff; } @@ -1759,10 +1761,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (neg_inner_op @0 { wide_int_to_tree (type, wi::to_wide (cst)); }) /* Last resort, use some unsigned type. */ (with { tree utype = unsigned_type_for (type); } - (view_convert (inner_op - (view_convert:utype @0) - (view_convert:utype - { drop_tree_overflow (cst); }))))))))))))) + (if (utype) + (view_convert (inner_op + (view_convert:utype @0) + (view_convert:utype + { drop_tree_overflow (cst); })))))))))))))) /* (CST1 - A) +- CST2 -> CST3 - A */ (for outer_op (plus minus) @@ -3460,8 +3463,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Disable this optimization if we're casting a function pointer type on targets that require function pointer canonicalization. */ && !(targetm.have_canonicalize_funcptr_for_compare () - && TREE_CODE (TREE_TYPE (@00)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_TYPE (@00))) == FUNCTION_TYPE) + && POINTER_TYPE_P (TREE_TYPE (@00)) + && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@00)))) && single_use (@0)) (if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0)) && (TREE_CODE (@10) == INTEGER_CST diff --git a/contrib/gcc-8.0/gcc/omp-expand.c b/contrib/gcc-8.0/gcc/omp-expand.c index c7d30ea396..4ea260e3f4 100644 --- a/contrib/gcc-8.0/gcc/omp-expand.c +++ b/contrib/gcc-8.0/gcc/omp-expand.c @@ -56,7 +56,6 @@ along with GCC; see the file COPYING3. If not see #include "gomp-constants.h" #include "gimple-pretty-print.h" #include "hsa-common.h" -#include "debug.h" #include "stringpool.h" #include "attribs.h" @@ -507,27 +506,43 @@ parallel_needs_hsa_kernel_p (struct omp_region *region) function will be emitted with the correct lexical scope. */ static void -adjust_context_and_scope (tree entry_block, tree child_fndecl) +adjust_context_and_scope (struct omp_region *region, tree entry_block, + tree child_fndecl) { + tree parent_fndecl = NULL_TREE; + gimple *entry_stmt; + /* OMP expansion expands inner regions before outer ones, so if + we e.g. have explicit task region nested in parallel region, when + expanding the task region current_function_decl will be the original + source function, but we actually want to use as context the child + function of the parallel. */ + for (region = region->outer; + region && parent_fndecl == NULL_TREE; region = region->outer) + switch (region->type) + { + case GIMPLE_OMP_PARALLEL: + case GIMPLE_OMP_TASK: + entry_stmt = last_stmt (region->entry); + parent_fndecl = gimple_omp_taskreg_child_fn (entry_stmt); + break; + case GIMPLE_OMP_TARGET: + entry_stmt = last_stmt (region->entry); + parent_fndecl + = gimple_omp_target_child_fn (as_a (entry_stmt)); + break; + default: + break; + } + + if (parent_fndecl == NULL_TREE) + parent_fndecl = current_function_decl; + DECL_CONTEXT (child_fndecl) = parent_fndecl; + if (entry_block != NULL_TREE && TREE_CODE (entry_block) == BLOCK) { tree b = BLOCK_SUPERCONTEXT (entry_block); - if (TREE_CODE (b) == BLOCK) { - tree parent_fndecl; - - /* Follow supercontext chain until the parent fndecl - is found. */ - for (parent_fndecl = BLOCK_SUPERCONTEXT (b); - TREE_CODE (parent_fndecl) == BLOCK; - parent_fndecl = BLOCK_SUPERCONTEXT (parent_fndecl)) - ; - - gcc_assert (TREE_CODE (parent_fndecl) == FUNCTION_DECL); - - DECL_CONTEXT (child_fndecl) = parent_fndecl; - DECL_CHAIN (child_fndecl) = BLOCK_VARS (b); BLOCK_VARS (b) = child_fndecl; } @@ -703,8 +718,6 @@ expand_parallel_call (struct omp_region *region, basic_block bb, tree child_fndecl = gimple_omp_parallel_child_fn (entry_stmt); t2 = build_fold_addr_expr (child_fndecl); - adjust_context_and_scope (gimple_block (entry_stmt), child_fndecl); - vec_alloc (args, 4 + vec_safe_length (ws_args)); args->quick_push (t2); args->quick_push (t1); @@ -1294,11 +1307,6 @@ expand_omp_taskreg (struct omp_region *region) else block = gimple_block (entry_stmt); - /* Make sure to generate early debug for the function before - outlining anything. */ - if (! gimple_in_ssa_p (cfun)) - (*debug_hooks->early_global_decl) (cfun->decl); - new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block); if (exit_bb) single_succ_edge (new_bb)->flags = EDGE_FALLTHRU; @@ -1379,6 +1387,8 @@ expand_omp_taskreg (struct omp_region *region) } } + adjust_context_and_scope (region, gimple_block (entry_stmt), child_fn); + if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL) expand_parallel_call (region, new_bb, as_a (entry_stmt), ws_args); @@ -1947,6 +1957,11 @@ extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb, t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t); stmt = gimple_build_cond_empty (t); gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING); + if (walk_tree (gimple_cond_lhs_ptr (as_a (stmt)), + expand_omp_regimplify_p, NULL, NULL) + || walk_tree (gimple_cond_rhs_ptr (as_a (stmt)), + expand_omp_regimplify_p, NULL, NULL)) + gimple_regimplify_operands (stmt, &gsi); e = make_edge (bb, body_bb, EDGE_TRUE_VALUE); e->probability = profile_probability::guessed_always ().apply_scale (7, 8); } @@ -3029,20 +3044,21 @@ expand_omp_for_generic (struct omp_region *region, if (fd->ordered && counts[fd->collapse - 1] == NULL_TREE) { + tree tem; if (fd->collapse > 1) - t = fd->loop.v; + tem = fd->loop.v; else { - t = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[0].v), - fd->loops[0].v, fd->loops[0].n1); - t = fold_convert (fd->iter_type, t); + tem = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[0].v), + fd->loops[0].v, fd->loops[0].n1); + tem = fold_convert (fd->iter_type, tem); } tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered], size_zero_node, NULL_TREE, NULL_TREE); - t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, - true, GSI_SAME_STMT); - expand_omp_build_assign (&gsi, aref, t); + tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, + true, GSI_SAME_STMT); + expand_omp_build_assign (&gsi, aref, tem); } t = build2 (fd->loop.cond_code, boolean_type_node, @@ -7042,11 +7058,6 @@ expand_omp_target (struct omp_region *region) gsi_remove (&gsi, true); } - /* Make sure to generate early debug for the function before - outlining anything. */ - if (! gimple_in_ssa_p (cfun)) - (*debug_hooks->early_global_decl) (cfun->decl); - /* Move the offloading region into CHILD_CFUN. */ block = gimple_block (entry_stmt); @@ -7123,6 +7134,8 @@ expand_omp_target (struct omp_region *region) dump_function_header (dump_file, child_fn, dump_flags); dump_function_to_file (child_fn, dump_file, dump_flags); } + + adjust_context_and_scope (region, gimple_block (entry_stmt), child_fn); } /* Emit a library call to launch the offloading region, or do data @@ -7619,11 +7632,6 @@ grid_expand_target_grid_body (struct omp_region *target) init_tree_ssa (cfun); pop_cfun (); - /* Make sure to generate early debug for the function before - outlining anything. */ - if (! gimple_in_ssa_p (cfun)) - (*debug_hooks->early_global_decl) (cfun->decl); - tree old_parm_decl = DECL_ARGUMENTS (kern_fndecl); gcc_assert (!DECL_CHAIN (old_parm_decl)); tree new_parm_decl = copy_node (DECL_ARGUMENTS (kern_fndecl)); diff --git a/contrib/gcc-8.0/gcc/omp-low.c b/contrib/gcc-8.0/gcc/omp-low.c index d8588b9fae..144076f080 100644 --- a/contrib/gcc-8.0/gcc/omp-low.c +++ b/contrib/gcc-8.0/gcc/omp-low.c @@ -1190,13 +1190,16 @@ scan_sharing_clauses (tree clauses, omp_context *ctx, /* Global variables with "omp declare target" attribute don't need to be copied, the receiver side will use them directly. However, global variables with "omp declare target link" - attribute need to be copied. */ + attribute need to be copied. Or when ALWAYS modifier is used. */ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && DECL_P (decl) && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER && (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_REFERENCE)) || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) + && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TO + && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_FROM + && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_TOFROM && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)) && varpool_node::get_create (decl)->offloadable && !lookup_attribute ("omp declare target link", @@ -2832,14 +2835,25 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx) case GIMPLE_OMP_FOR: if (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP) goto ordered_in_taskloop; - if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt), - OMP_CLAUSE_ORDERED) == NULL) + tree o; + o = omp_find_clause (gimple_omp_for_clauses (ctx->stmt), + OMP_CLAUSE_ORDERED); + if (o == NULL) { error_at (gimple_location (stmt), "% region must be closely nested inside " "a loop region with an % clause"); return false; } + if (OMP_CLAUSE_ORDERED_EXPR (o) != NULL_TREE + && omp_find_clause (c, OMP_CLAUSE_DEPEND) == NULL_TREE) + { + error_at (gimple_location (stmt), + "% region without % clause may " + "not be closely nested inside a loop region with " + "an % clause with a parameter"); + return false; + } return true; case GIMPLE_OMP_TARGET: if (gimple_omp_target_kind (ctx->stmt) @@ -7099,6 +7113,7 @@ create_task_copyfn (gomp_task *task_stmt, omp_context *ctx) splay_tree_node n; struct omp_taskcopy_context tcctx; location_t loc = gimple_location (task_stmt); + size_t looptempno = 0; child_fn = gimple_omp_task_copy_fn (task_stmt); child_cfun = DECL_STRUCT_FUNCTION (child_fn); @@ -7212,6 +7227,15 @@ create_task_copyfn (gomp_task *task_stmt, omp_context *ctx) t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); append_to_statement_list (t, &list); break; + case OMP_CLAUSE__LOOPTEMP_: + /* Fields for first two _looptemp_ clauses are initialized by + GOMP_taskloop*, the rest are handled like firstprivate. */ + if (looptempno < 2) + { + looptempno++; + break; + } + /* FALLTHRU */ case OMP_CLAUSE_FIRSTPRIVATE: decl = OMP_CLAUSE_DECL (c); if (is_variable_sized (decl)) @@ -7237,7 +7261,10 @@ create_task_copyfn (gomp_task *task_stmt, omp_context *ctx) src = decl; dst = build_simple_mem_ref_loc (loc, arg); dst = omp_build_component_ref (dst, f); - t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__LOOPTEMP_) + t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); + else + t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src); append_to_statement_list (t, &list); break; case OMP_CLAUSE_PRIVATE: diff --git a/contrib/gcc-8.0/gcc/omp-simd-clone.c b/contrib/gcc-8.0/gcc/omp-simd-clone.c index b15adf0bad..8b4cd9cb72 100644 --- a/contrib/gcc-8.0/gcc/omp-simd-clone.c +++ b/contrib/gcc-8.0/gcc/omp-simd-clone.c @@ -242,6 +242,10 @@ simd_clone_clauses_extract (struct cgraph_node *node, tree clauses, } case OMP_CLAUSE_ALIGNED: { + /* Ignore aligned (x) for declare simd, for the ABI we really + need an alignment specified. */ + if (OMP_CLAUSE_ALIGNED_ALIGNMENT (t) == NULL_TREE) + break; tree decl = OMP_CLAUSE_DECL (t); int argno = tree_to_uhwi (decl); clone_info->args[argno].alignment @@ -996,6 +1000,8 @@ ipa_simd_modify_function_body (struct cgraph_node *node, if (greturn *return_stmt = dyn_cast (stmt)) { tree retval = gimple_return_retval (return_stmt); + edge e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun)); + e->flags |= EDGE_FALLTHRU; if (!retval) { gsi_remove (&gsi, true); @@ -1013,6 +1019,21 @@ ipa_simd_modify_function_body (struct cgraph_node *node, if (info.modified) { update_stmt (stmt); + /* If the above changed the var of a debug bind into something + different, remove the debug stmt. We could also for all the + replaced parameters add VAR_DECLs for debug info purposes, + add debug stmts for those to be the simd array accesses and + replace debug stmt var operand with that var. Debugging of + vectorized loops doesn't work too well, so don't bother for + now. */ + if ((gimple_debug_bind_p (stmt) + && !DECL_P (gimple_debug_bind_get_var (stmt))) + || (gimple_debug_source_bind_p (stmt) + && !DECL_P (gimple_debug_source_bind_get_var (stmt)))) + { + gsi_remove (&gsi, true); + continue; + } if (maybe_clean_eh_stmt (stmt)) gimple_purge_dead_eh_edges (gimple_bb (stmt)); } @@ -1137,14 +1158,9 @@ simd_clone_adjust (struct cgraph_node *node) incr_bb = create_empty_bb (orig_exit); incr_bb->count = profile_count::zero (); add_bb_to_loop (incr_bb, body_bb->loop_father); - /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty - flag. Set it now to be a FALLTHRU_EDGE. */ - gcc_assert (EDGE_COUNT (orig_exit->succs) == 1); - EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU; - for (unsigned i = 0; - i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i) + while (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)) { - edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i); + edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0); redirect_edge_succ (e, incr_bb); incr_bb->count += e->count (); } diff --git a/contrib/gcc-8.0/gcc/optabs.c b/contrib/gcc-8.0/gcc/optabs.c index 53a147c8ef..b31016c05e 100644 --- a/contrib/gcc-8.0/gcc/optabs.c +++ b/contrib/gcc-8.0/gcc/optabs.c @@ -55,7 +55,7 @@ void debug_optab_libfuncs (void); /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to the result of operation CODE applied to OP0 (and OP1 if it is a binary - operation). + operation). OP0_MODE is OP0's mode. If the last insn does not set TARGET, don't do anything, but return 1. @@ -64,7 +64,8 @@ void debug_optab_libfuncs (void); try again, ensuring that TARGET is not one of the operands. */ static int -add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1) +add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, + rtx op1, machine_mode op0_mode) { rtx_insn *last_insn; rtx set; @@ -136,16 +137,16 @@ add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op case POPCOUNT: case PARITY: case BSWAP: - if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0)) + if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode) { - note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0)); - if (GET_MODE_UNIT_SIZE (GET_MODE (op0)) + note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0)); + if (GET_MODE_UNIT_SIZE (op0_mode) > GET_MODE_UNIT_SIZE (GET_MODE (target))) note = simplify_gen_unary (TRUNCATE, GET_MODE (target), - note, GET_MODE (op0)); + note, op0_mode); else note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target), - note, GET_MODE (op0)); + note, op0_mode); break; } /* FALLTHRU */ @@ -1095,7 +1096,7 @@ expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab, if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && ! add_equal_note (pat, ops[0].value, optab_to_code (binoptab), - ops[1].value, ops[2].value)) + ops[1].value, ops[2].value, mode0)) { delete_insns_since (last); return expand_binop (mode, binoptab, op0, op1, NULL_RTX, @@ -2260,7 +2261,7 @@ expand_doubleword_clz (scalar_int_mode mode, rtx op0, rtx target) seq = get_insns (); end_sequence (); - add_equal_note (seq, target, CLZ, xop0, 0); + add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode); emit_insn (seq); return target; @@ -2302,7 +2303,7 @@ expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target) seq = get_insns (); end_sequence (); - add_equal_note (seq, t, POPCOUNT, op0, 0); + add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode); emit_insn (seq); return t; } @@ -2473,7 +2474,7 @@ expand_ctz (scalar_int_mode mode, rtx op0, rtx target) seq = get_insns (); end_sequence (); - add_equal_note (seq, temp, CTZ, op0, 0); + add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode); emit_insn (seq); return temp; } @@ -2551,7 +2552,7 @@ expand_ffs (scalar_int_mode mode, rtx op0, rtx target) seq = get_insns (); end_sequence (); - add_equal_note (seq, temp, FFS, op0, 0); + add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode); emit_insn (seq); return temp; @@ -2698,7 +2699,7 @@ expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target, if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && ! add_equal_note (pat, ops[0].value, optab_to_code (unoptab), - ops[1].value, NULL_RTX)) + ops[1].value, NULL_RTX, mode)) { delete_insns_since (last); return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp); @@ -3550,7 +3551,8 @@ maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0, if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN) - add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX); + add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX, + GET_MODE (op0)); emit_insn (pat); @@ -3855,7 +3857,7 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size, /* Must make sure the size fits the insn's mode. */ if (CONST_INT_P (size) - ? INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)) + ? UINTVAL (size) > GET_MODE_MASK (cmp_mode) : (GET_MODE_BITSIZE (as_a (GET_MODE (size))) > GET_MODE_BITSIZE (cmp_mode))) continue; @@ -3874,7 +3876,7 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size, goto fail; /* Otherwise call a library function. */ - result = emit_block_comp_via_libcall (XEXP (x, 0), XEXP (y, 0), size); + result = emit_block_comp_via_libcall (x, y, size); x = result; y = const0_rtx; diff --git a/contrib/gcc-8.0/gcc/optc-save-gen.awk b/contrib/gcc-8.0/gcc/optc-save-gen.awk index 1a365fc883..7cf2223210 100644 --- a/contrib/gcc-8.0/gcc/optc-save-gen.awk +++ b/contrib/gcc-8.0/gcc/optc-save-gen.awk @@ -81,7 +81,7 @@ print "void"; print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts)"; print "{"; -n_opt_char = 3; +n_opt_char = 4; n_opt_short = 0; n_opt_int = 0; n_opt_enum = 0; @@ -89,9 +89,11 @@ n_opt_other = 0; var_opt_char[0] = "optimize"; var_opt_char[1] = "optimize_size"; var_opt_char[2] = "optimize_debug"; +var_opt_char[3] = "optimize_fast"; var_opt_range["optimize"] = "0, 255"; var_opt_range["optimize_size"] = "0, 1"; var_opt_range["optimize_debug"] = "0, 1"; +var_opt_range["optimize_fast"] = "0, 1"; # Sort by size to mimic how the structure is laid out to be friendlier to the # cache. @@ -732,13 +734,15 @@ for (i = 0; i < n_target_val; i++) { print "}"; -n_opt_val = 3; +n_opt_val = 4; var_opt_val[0] = "x_optimize" var_opt_val_type[0] = "char " var_opt_val[1] = "x_optimize_size" -var_opt_val[2] = "x_optimize_debug" var_opt_val_type[1] = "char " +var_opt_val[2] = "x_optimize_debug" var_opt_val_type[2] = "char " +var_opt_val[3] = "x_optimize_fast" +var_opt_val_type[3] = "char " for (i = 0; i < n_opts; i++) { if (flag_set_p("(Optimization|PerFunction)", flags[i])) { name = var_name(flags[i]) diff --git a/contrib/gcc-8.0/gcc/opth-gen.awk b/contrib/gcc-8.0/gcc/opth-gen.awk index fecd4b8a0b..e490b397b6 100644 --- a/contrib/gcc-8.0/gcc/opth-gen.awk +++ b/contrib/gcc-8.0/gcc/opth-gen.awk @@ -132,7 +132,7 @@ print "/* Structure to save/restore optimization and target specific options. * print "struct GTY(()) cl_optimization"; print "{"; -n_opt_char = 3; +n_opt_char = 4; n_opt_short = 0; n_opt_int = 0; n_opt_enum = 0; @@ -140,6 +140,7 @@ n_opt_other = 0; var_opt_char[0] = "unsigned char x_optimize"; var_opt_char[1] = "unsigned char x_optimize_size"; var_opt_char[2] = "unsigned char x_optimize_debug"; +var_opt_char[3] = "unsigned char x_optimize_fast"; for (i = 0; i < n_opts; i++) { if (flag_set_p("(Optimization|PerFunction)", flags[i])) { diff --git a/contrib/gcc-8.0/gcc/opts.c b/contrib/gcc-8.0/gcc/opts.c index 33efcc0d6e..442f250f3a 100644 --- a/contrib/gcc-8.0/gcc/opts.c +++ b/contrib/gcc-8.0/gcc/opts.c @@ -657,7 +657,16 @@ default_options_optimization (struct gcc_options *opts, /* For -O1 only do loop invariant motion for very small loops. */ maybe_set_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP, - opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000, + opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) + : default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) / 10, + opts->x_param_values, opts_set->x_param_values); + + /* For -O1 reduce the maximum number of active local stores for RTL DSE + since this can consume huge amounts of memory (PR89115). */ + maybe_set_param_value + (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES, + opt2 ? default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) + : default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10, opts->x_param_values, opts_set->x_param_values); /* At -Ofast, allow store motion to introduce potential race conditions. */ diff --git a/contrib/gcc-8.0/gcc/passes.c b/contrib/gcc-8.0/gcc/passes.c index ad0a912e13..65ad690f6d 100644 --- a/contrib/gcc-8.0/gcc/passes.c +++ b/contrib/gcc-8.0/gcc/passes.c @@ -363,9 +363,9 @@ finish_optimization_passes (void) if (optimize > 0) { - dumps->dump_start (pass_profile_1->static_pass_number, NULL); + dumps->dump_start (pass_combine_1->static_pass_number, NULL); print_combine_total_stats (); - dumps->dump_finish (pass_profile_1->static_pass_number); + dumps->dump_finish (pass_combine_1->static_pass_number); } /* Do whatever is necessary to finish printing the graphs. */ diff --git a/contrib/gcc-8.0/gcc/pretty-print.c b/contrib/gcc-8.0/gcc/pretty-print.c index 8babbffda7..6243aed3da 100644 --- a/contrib/gcc-8.0/gcc/pretty-print.c +++ b/contrib/gcc-8.0/gcc/pretty-print.c @@ -640,6 +640,16 @@ sgr_set_it: { attrib_add |= sb.wAttributes & ~attrib_rm; } + if (attrib_add & COMMON_LVB_REVERSE_VIDEO) + { + /* COMMON_LVB_REVERSE_VIDEO is only effective for DBCS. + * Swap foreground and background colors by hand. + */ + attrib_add = (attrib_add & 0xFF00) + | ((attrib_add & 0x00F0) >> 4) + | ((attrib_add & 0x000F) << 4); + attrib_add &= ~COMMON_LVB_REVERSE_VIDEO; + } SetConsoleTextAttribute (h, attrib_add); break; } @@ -684,7 +694,6 @@ mingw_ansi_fputs (const char *str, FILE *fp) /* If it is not a console, write everything as-is. */ write_all (h, read, strlen (read)); - _close ((intptr_t) h); return 1; } @@ -1482,23 +1491,38 @@ pp_clear_output_area (pretty_printer *pp) pp_buffer (pp)->line_length = 0; } -/* Set PREFIX for PRETTY-PRINTER. */ +/* Set PREFIX for PRETTY-PRINTER, taking ownership of PREFIX, which + will eventually be free-ed. */ + void -pp_set_prefix (pretty_printer *pp, const char *prefix) +pp_set_prefix (pretty_printer *pp, char *prefix) { + free (pp->prefix); pp->prefix = prefix; pp_set_real_maximum_length (pp); pp->emitted_prefix = false; pp_indentation (pp) = 0; } +/* Take ownership of PP's prefix, setting it to NULL. + This allows clients to save, overide, and then restore an existing + prefix, without it being free-ed. */ + +char * +pp_take_prefix (pretty_printer *pp) +{ + char *result = pp->prefix; + pp->prefix = NULL; + return result; +} + /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */ void pp_destroy_prefix (pretty_printer *pp) { if (pp->prefix != NULL) { - free (CONST_CAST (char *, pp->prefix)); + free (pp->prefix); pp->prefix = NULL; } } @@ -1535,10 +1559,9 @@ pp_emit_prefix (pretty_printer *pp) } } -/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH - characters per line. */ +/* Construct a PRETTY-PRINTER of MAXIMUM_LENGTH characters per line. */ -pretty_printer::pretty_printer (const char *p, int l) +pretty_printer::pretty_printer (int maximum_length) : buffer (new (XCNEW (output_buffer)) output_buffer ()), prefix (), padding (pp_none), @@ -1552,10 +1575,10 @@ pretty_printer::pretty_printer (const char *p, int l) translate_identifiers (true), show_color () { - pp_line_cutoff (this) = l; + pp_line_cutoff (this) = maximum_length; /* By default, we emit prefixes once per message. */ pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE; - pp_set_prefix (this, p); + pp_set_prefix (this, NULL); } pretty_printer::~pretty_printer () @@ -1564,6 +1587,7 @@ pretty_printer::~pretty_printer () delete m_format_postprocessor; buffer->~output_buffer (); XDELETE (buffer); + free (prefix); } /* Append a string delimited by START and END to the output area of diff --git a/contrib/gcc-8.0/gcc/pretty-print.h b/contrib/gcc-8.0/gcc/pretty-print.h index 56abe03e46..0d67e30805 100644 --- a/contrib/gcc-8.0/gcc/pretty-print.h +++ b/contrib/gcc-8.0/gcc/pretty-print.h @@ -215,17 +215,18 @@ class format_postprocessor and add additional fields they need. */ struct pretty_printer { - // Default construct a pretty printer with specified prefix - // and a maximum line length cut off limit. - explicit pretty_printer (const char* = NULL, int = 0); + /* Default construct a pretty printer with specified + maximum line length cut off limit. */ + explicit pretty_printer (int = 0); virtual ~pretty_printer (); /* Where we print external representation of ENTITY. */ output_buffer *buffer; - /* The prefix for each new line. */ - const char *prefix; + /* The prefix for each new line. If non-NULL, this is "owned" by the + pretty_printer, and will eventually be free-ed. */ + char *prefix; /* Where to put whitespace around the entity being formatted. */ pp_padding padding; @@ -338,7 +339,8 @@ pp_get_prefix (const pretty_printer *pp) { return pp->prefix; } #define pp_buffer(PP) (PP)->buffer extern void pp_set_line_maximum_length (pretty_printer *, int); -extern void pp_set_prefix (pretty_printer *, const char *); +extern void pp_set_prefix (pretty_printer *, char *); +extern char *pp_take_prefix (pretty_printer *); extern void pp_destroy_prefix (pretty_printer *); extern int pp_remaining_character_count_for_line (pretty_printer *); extern void pp_clear_output_area (pretty_printer *); diff --git a/contrib/gcc-8.0/gcc/profile-count.h b/contrib/gcc-8.0/gcc/profile-count.h index c83fa3beb8..a4930750b5 100644 --- a/contrib/gcc-8.0/gcc/profile-count.h +++ b/contrib/gcc-8.0/gcc/profile-count.h @@ -643,7 +643,17 @@ private: static const uint64_t max_count = ((uint64_t) 1 << n_bits) - 2; static const uint64_t uninitialized_count = ((uint64_t) 1 << n_bits) - 1; - uint64_t m_val : n_bits; +#if defined (__arm__) && (__GNUC__ >= 6 && __GNUC__ <= 8) + /* Work-around for PR88469. A bug in the gcc-6/7/8 PCS layout code + incorrectly detects the alignment of a structure where the only + 64-bit aligned object is a bit-field. We force the alignment of + the entire field to mitigate this. */ +#define UINT64_BIT_FIELD_ALIGN __attribute__ ((aligned(8))) +#else +#define UINT64_BIT_FIELD_ALIGN +#endif + uint64_t UINT64_BIT_FIELD_ALIGN m_val : n_bits; +#undef UINT64_BIT_FIELD_ALIGN enum profile_quality m_quality : 3; /* Return true if both values can meaningfully appear in single function diff --git a/contrib/gcc-8.0/gcc/profile.c b/contrib/gcc-8.0/gcc/profile.c index 6fde0fd29d..eb9f7d5266 100644 --- a/contrib/gcc-8.0/gcc/profile.c +++ b/contrib/gcc-8.0/gcc/profile.c @@ -977,6 +977,25 @@ compare_freqs (const void *p1, const void *p2) return e2->dest->index - e1->dest->index; } +/* Only read execution count for thunks. */ + +void +read_thunk_profile (struct cgraph_node *node) +{ + tree old = current_function_decl; + current_function_decl = node->decl; + gcov_type *counts = get_coverage_counts (GCOV_COUNTER_ARCS, 1, 0, 0, NULL); + if (counts) + { + node->callees->count = node->count + = profile_count::from_gcov_type (counts[0]); + free (counts); + } + current_function_decl = old; + return; +} + + /* Instrument and/or analyze program behavior based on program the CFG. This function creates a representation of the control flow graph (of @@ -997,7 +1016,7 @@ compare_freqs (const void *p1, const void *p2) Main entry point of this file. */ void -branch_prob (void) +branch_prob (bool thunk) { basic_block bb; unsigned i; @@ -1012,118 +1031,121 @@ branch_prob (void) flow_call_edges_add (NULL); add_noreturn_fake_exit_edges (); - /* We can't handle cyclic regions constructed using abnormal edges. - To avoid these we replace every source of abnormal edge by a fake - edge from entry node and every destination by fake edge to exit. - This keeps graph acyclic and our calculation exact for all normal - edges except for exit and entrance ones. - - We also add fake exit edges for each call and asm statement in the - basic, since it may not return. */ - - FOR_EACH_BB_FN (bb, cfun) + if (!thunk) { - int need_exit_edge = 0, need_entry_edge = 0; - int have_exit_edge = 0, have_entry_edge = 0; - edge e; - edge_iterator ei; + /* We can't handle cyclic regions constructed using abnormal edges. + To avoid these we replace every source of abnormal edge by a fake + edge from entry node and every destination by fake edge to exit. + This keeps graph acyclic and our calculation exact for all normal + edges except for exit and entrance ones. - /* Functions returning multiple times are not handled by extra edges. - Instead we simply allow negative counts on edges from exit to the - block past call and corresponding probabilities. We can't go - with the extra edges because that would result in flowgraph that - needs to have fake edges outside the spanning tree. */ + We also add fake exit edges for each call and asm statement in the + basic, since it may not return. */ - FOR_EACH_EDGE (e, ei, bb->succs) + FOR_EACH_BB_FN (bb, cfun) { - gimple_stmt_iterator gsi; - gimple *last = NULL; - - /* It may happen that there are compiler generated statements - without a locus at all. Go through the basic block from the - last to the first statement looking for a locus. */ - for (gsi = gsi_last_nondebug_bb (bb); - !gsi_end_p (gsi); - gsi_prev_nondebug (&gsi)) + int need_exit_edge = 0, need_entry_edge = 0; + int have_exit_edge = 0, have_entry_edge = 0; + edge e; + edge_iterator ei; + + /* Functions returning multiple times are not handled by extra edges. + Instead we simply allow negative counts on edges from exit to the + block past call and corresponding probabilities. We can't go + with the extra edges because that would result in flowgraph that + needs to have fake edges outside the spanning tree. */ + + FOR_EACH_EDGE (e, ei, bb->succs) { - last = gsi_stmt (gsi); - if (!RESERVED_LOCATION_P (gimple_location (last))) - break; - } + gimple_stmt_iterator gsi; + gimple *last = NULL; + + /* It may happen that there are compiler generated statements + without a locus at all. Go through the basic block from the + last to the first statement looking for a locus. */ + for (gsi = gsi_last_nondebug_bb (bb); + !gsi_end_p (gsi); + gsi_prev_nondebug (&gsi)) + { + last = gsi_stmt (gsi); + if (!RESERVED_LOCATION_P (gimple_location (last))) + break; + } - /* Edge with goto locus might get wrong coverage info unless - it is the only edge out of BB. - Don't do that when the locuses match, so - if (blah) goto something; - is not computed twice. */ - if (last - && gimple_has_location (last) - && !RESERVED_LOCATION_P (e->goto_locus) - && !single_succ_p (bb) - && (LOCATION_FILE (e->goto_locus) - != LOCATION_FILE (gimple_location (last)) - || (LOCATION_LINE (e->goto_locus) - != LOCATION_LINE (gimple_location (last))))) + /* Edge with goto locus might get wrong coverage info unless + it is the only edge out of BB. + Don't do that when the locuses match, so + if (blah) goto something; + is not computed twice. */ + if (last + && gimple_has_location (last) + && !RESERVED_LOCATION_P (e->goto_locus) + && !single_succ_p (bb) + && (LOCATION_FILE (e->goto_locus) + != LOCATION_FILE (gimple_location (last)) + || (LOCATION_LINE (e->goto_locus) + != LOCATION_LINE (gimple_location (last))))) + { + basic_block new_bb = split_edge (e); + edge ne = single_succ_edge (new_bb); + ne->goto_locus = e->goto_locus; + } + if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL)) + && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) + need_exit_edge = 1; + if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) + have_exit_edge = 1; + } + FOR_EACH_EDGE (e, ei, bb->preds) { - basic_block new_bb = split_edge (e); - edge ne = single_succ_edge (new_bb); - ne->goto_locus = e->goto_locus; + if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL)) + && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)) + need_entry_edge = 1; + if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)) + have_entry_edge = 1; } - if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL)) - && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) - need_exit_edge = 1; - if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) - have_exit_edge = 1; - } - FOR_EACH_EDGE (e, ei, bb->preds) - { - if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL)) - && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)) - need_entry_edge = 1; - if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)) - have_entry_edge = 1; - } - if (need_exit_edge && !have_exit_edge) - { - if (dump_file) - fprintf (dump_file, "Adding fake exit edge to bb %i\n", - bb->index); - make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE); - } - if (need_entry_edge && !have_entry_edge) - { - if (dump_file) - fprintf (dump_file, "Adding fake entry edge to bb %i\n", - bb->index); - make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FAKE); - /* Avoid bbs that have both fake entry edge and also some - exit edge. One of those edges wouldn't be added to the - spanning tree, but we can't instrument any of them. */ - if (have_exit_edge || need_exit_edge) + if (need_exit_edge && !have_exit_edge) + { + if (dump_file) + fprintf (dump_file, "Adding fake exit edge to bb %i\n", + bb->index); + make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE); + } + if (need_entry_edge && !have_entry_edge) { - gimple_stmt_iterator gsi; - gimple *first; - - gsi = gsi_start_nondebug_after_labels_bb (bb); - gcc_checking_assert (!gsi_end_p (gsi)); - first = gsi_stmt (gsi); - /* Don't split the bbs containing __builtin_setjmp_receiver - or ABNORMAL_DISPATCHER calls. These are very - special and don't expect anything to be inserted before - them. */ - if (is_gimple_call (first) - && (gimple_call_builtin_p (first, BUILT_IN_SETJMP_RECEIVER) - || (gimple_call_flags (first) & ECF_RETURNS_TWICE) - || (gimple_call_internal_p (first) - && (gimple_call_internal_fn (first) - == IFN_ABNORMAL_DISPATCHER)))) - continue; - if (dump_file) - fprintf (dump_file, "Splitting bb %i after labels\n", + fprintf (dump_file, "Adding fake entry edge to bb %i\n", bb->index); - split_block_after_labels (bb); + make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FAKE); + /* Avoid bbs that have both fake entry edge and also some + exit edge. One of those edges wouldn't be added to the + spanning tree, but we can't instrument any of them. */ + if (have_exit_edge || need_exit_edge) + { + gimple_stmt_iterator gsi; + gimple *first; + + gsi = gsi_start_nondebug_after_labels_bb (bb); + gcc_checking_assert (!gsi_end_p (gsi)); + first = gsi_stmt (gsi); + /* Don't split the bbs containing __builtin_setjmp_receiver + or ABNORMAL_DISPATCHER calls. These are very + special and don't expect anything to be inserted before + them. */ + if (is_gimple_call (first) + && (gimple_call_builtin_p (first, BUILT_IN_SETJMP_RECEIVER) + || (gimple_call_flags (first) & ECF_RETURNS_TWICE) + || (gimple_call_internal_p (first) + && (gimple_call_internal_fn (first) + == IFN_ABNORMAL_DISPATCHER)))) + continue; + + if (dump_file) + fprintf (dump_file, "Splitting bb %i after labels\n", + bb->index); + split_block_after_labels (bb); + } } } } @@ -1155,7 +1177,18 @@ branch_prob (void) on the spanning tree. We insert as many abnormal and critical edges as possible to minimize number of edge splits necessary. */ - find_spanning_tree (el); + if (!thunk) + find_spanning_tree (el); + else + { + edge e; + edge_iterator ei; + /* Keep only edge from entry block to be instrumented. */ + FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_EDGE (e, ei, bb->succs) + EDGE_INFO (e)->ignore = true; + } + /* Fake edges that are not on the tree will not be instrumented, so mark them ignored. */ @@ -1195,8 +1228,17 @@ branch_prob (void) the checksum in only once place, since it depends on the shape of the control flow which can change during various transformations. */ - cfg_checksum = coverage_compute_cfg_checksum (cfun); - lineno_checksum = coverage_compute_lineno_checksum (); + if (thunk) + { + /* At stream in time we do not have CFG, so we can not do checksums. */ + cfg_checksum = 0; + lineno_checksum = 0; + } + else + { + cfg_checksum = coverage_compute_cfg_checksum (cfun); + lineno_checksum = coverage_compute_lineno_checksum (); + } /* Write the data from which gcov can reconstruct the basic block graph and function line numbers (the gcno file). */ diff --git a/contrib/gcc-8.0/gcc/regcprop.c b/contrib/gcc-8.0/gcc/regcprop.c index a664f76a8b..18132425ab 100644 --- a/contrib/gcc-8.0/gcc/regcprop.c +++ b/contrib/gcc-8.0/gcc/regcprop.c @@ -848,6 +848,12 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) && reg_overlap_mentioned_p (XEXP (link, 0), SET_SRC (set))) set = NULL; } + + /* We need to keep CFI info correct, and the same on all paths, + so we cannot normally replace the registers REG_CFA_REGISTER + refers to. Bail. */ + if (REG_NOTE_KIND (link) == REG_CFA_REGISTER) + goto did_replacement; } /* Special-case plain move instructions, since we may well diff --git a/contrib/gcc-8.0/gcc/regrename.c b/contrib/gcc-8.0/gcc/regrename.c index 45754812f6..84240930e3 100644 --- a/contrib/gcc-8.0/gcc/regrename.c +++ b/contrib/gcc-8.0/gcc/regrename.c @@ -1661,7 +1661,8 @@ build_def_use (basic_block bb) (6) For any non-earlyclobber write we find in an operand, make a new chain or mark the hard register as live. (7) For any REG_UNUSED, close any chains we just opened. - (8) For any REG_CFA_RESTORE, kill any chain containing it. + (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain + containing its dest. We cannot deal with situations where we track a reg in one mode and see a reference in another mode; these will cause the chain @@ -1882,10 +1883,20 @@ build_def_use (basic_block bb) } /* Step 8: Kill the chains involving register restores. Those - should restore _that_ register. */ + should restore _that_ register. Similar for REG_CFA_REGISTER. */ for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) - if (REG_NOTE_KIND (note) == REG_CFA_RESTORE) - scan_rtx (insn, &XEXP (note, 0), NO_REGS, mark_all_read, OP_IN); + if (REG_NOTE_KIND (note) == REG_CFA_RESTORE + || REG_NOTE_KIND (note) == REG_CFA_REGISTER) + { + rtx *x = &XEXP (note, 0); + if (!*x) + x = &PATTERN (insn); + if (GET_CODE (*x) == PARALLEL) + x = &XVECEXP (*x, 0, 0); + if (GET_CODE (*x) == SET) + x = &SET_DEST (*x); + scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN); + } } else if (DEBUG_BIND_INSN_P (insn) && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn))) diff --git a/contrib/gcc-8.0/gcc/rtl.h b/contrib/gcc-8.0/gcc/rtl.h index 0341ba0161..51f70cd8c3 100644 --- a/contrib/gcc-8.0/gcc/rtl.h +++ b/contrib/gcc-8.0/gcc/rtl.h @@ -4033,6 +4033,9 @@ extern void init_lower_subreg (void); /* In gcse.c */ extern bool can_copy_p (machine_mode); extern bool can_assign_to_reg_without_clobbers_p (rtx, machine_mode); +extern rtx_insn *prepare_copy_insn (rtx, rtx); + +/* In cprop.c */ extern rtx fis_get_condition (rtx_insn *); /* In ira.c */ @@ -4344,6 +4347,25 @@ strip_offset_and_add (rtx x, poly_int64_pod *offset) return x; } +/* Return true if X is an operation that always operates on the full + registers for WORD_REGISTER_OPERATIONS architectures. */ + +inline bool +word_register_operation_p (const_rtx x) +{ + switch (GET_CODE (x)) + { + case ROTATE: + case ROTATERT: + case SIGN_EXTRACT: + case ZERO_EXTRACT: + return false; + + default: + return true; + } +} + /* gtype-desc.c. */ extern void gt_ggc_mx (rtx &); extern void gt_pch_nx (rtx &); diff --git a/contrib/gcc-8.0/gcc/rtlanal.c b/contrib/gcc-8.0/gcc/rtlanal.c index ac3662de3c..0e79e53fb6 100644 --- a/contrib/gcc-8.0/gcc/rtlanal.c +++ b/contrib/gcc-8.0/gcc/rtlanal.c @@ -1802,6 +1802,7 @@ reg_overlap_mentioned_p (const_rtx x, const_rtx in) recurse: switch (GET_CODE (x)) { + case CLOBBER: case STRICT_LOW_PART: case ZERO_EXTRACT: case SIGN_EXTRACT: @@ -4469,12 +4470,12 @@ nonzero_bits1 (const_rtx x, scalar_int_mode mode, const_rtx known_x, might be nonzero in its own mode, taking into account the fact that, on CISC machines, accessing an object in a wider mode generally causes the high-order bits to become undefined, so they are not known to be zero. - We extend this reasoning to RISC machines for rotate operations since the - semantics of the operations in the larger mode is not well defined. */ + We extend this reasoning to RISC machines for operations that might not + operate on the full registers. */ if (mode_width > xmode_width && xmode_width <= BITS_PER_WORD && xmode_width <= HOST_BITS_PER_WIDE_INT - && (!WORD_REGISTER_OPERATIONS || code == ROTATE || code == ROTATERT)) + && !(WORD_REGISTER_OPERATIONS && word_register_operation_p (x))) { nonzero &= cached_nonzero_bits (x, xmode, known_x, known_mode, known_ret); @@ -4742,13 +4743,16 @@ nonzero_bits1 (const_rtx x, scalar_int_mode mode, const_rtx known_x, nonzero &= cached_nonzero_bits (SUBREG_REG (x), mode, known_x, known_mode, known_ret); - /* On many CISC machines, accessing an object in a wider mode + /* On a typical CISC machine, accessing an object in a wider mode causes the high-order bits to become undefined. So they are - not known to be zero. */ + not known to be zero. + + On a typical RISC machine, we only have to worry about the way + loads are extended. Otherwise, if we get a reload for the inner + part, it may be loaded from the stack, and then we may lose all + the zero bits that existed before the store to the stack. */ rtx_code extend_op; if ((!WORD_REGISTER_OPERATIONS - /* If this is a typical RISC machine, we only have to worry - about the way loads are extended. */ || ((extend_op = load_extend_op (inner_mode)) == SIGN_EXTEND ? val_signbit_known_set_p (inner_mode, nonzero) : extend_op != ZERO_EXTEND) @@ -5009,10 +5013,9 @@ num_sign_bit_copies1 (const_rtx x, scalar_int_mode mode, const_rtx known_x, { /* If this machine does not do all register operations on the entire register and MODE is wider than the mode of X, we can say nothing - at all about the high-order bits. We extend this reasoning to every - machine for rotate operations since the semantics of the operations - in the larger mode is not well defined. */ - if (!WORD_REGISTER_OPERATIONS || code == ROTATE || code == ROTATERT) + at all about the high-order bits. We extend this reasoning to RISC + machines for operations that might not operate on full registers. */ + if (!(WORD_REGISTER_OPERATIONS && word_register_operation_p (x))) return 1; /* Likewise on machines that do, if the mode of the object is smaller @@ -5091,13 +5094,12 @@ num_sign_bit_copies1 (const_rtx x, scalar_int_mode mode, const_rtx known_x, /* For paradoxical SUBREGs on machines where all register operations affect the entire register, just look inside. Note that we are passing MODE to the recursive call, so the number of sign bit - copies will remain relative to that mode, not the inner mode. */ + copies will remain relative to that mode, not the inner mode. - /* This works only if loads sign extend. Otherwise, if we get a + This works only if loads sign extend. Otherwise, if we get a reload for the inner part, it may be loaded from the stack, and then we lose all sign bit copies that existed before the store to the stack. */ - if (WORD_REGISTER_OPERATIONS && load_extend_op (inner_mode) == SIGN_EXTEND && paradoxical_subreg_p (x) diff --git a/contrib/gcc-8.0/gcc/stor-layout.c b/contrib/gcc-8.0/gcc/stor-layout.c index 81f75a5eb7..d06e88a813 100644 --- a/contrib/gcc-8.0/gcc/stor-layout.c +++ b/contrib/gcc-8.0/gcc/stor-layout.c @@ -1685,14 +1685,21 @@ place_field (record_layout_info rli, tree field) { rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field)); - /* If we ended a bitfield before the full length of the type then - pad the struct out to the full length of the last type. */ - if ((DECL_CHAIN (field) == NULL - || TREE_CODE (DECL_CHAIN (field)) != FIELD_DECL) - && DECL_BIT_FIELD_TYPE (field) + /* If FIELD is the last field and doesn't end at the full length + of the type then pad the struct out to the full length of the + last type. */ + if (DECL_BIT_FIELD_TYPE (field) && !integer_zerop (DECL_SIZE (field))) - rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, - bitsize_int (rli->remaining_in_alignment)); + { + /* We have to scan, because non-field DECLS are also here. */ + tree probe = field; + while ((probe = DECL_CHAIN (probe))) + if (TREE_CODE (probe) == FIELD_DECL) + break; + if (!probe) + rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, + bitsize_int (rli->remaining_in_alignment)); + } normalize_rli (rli); } diff --git a/contrib/gcc-8.0/gcc/store-motion.c b/contrib/gcc-8.0/gcc/store-motion.c index ca2d8fdf0c..139b390765 100644 --- a/contrib/gcc-8.0/gcc/store-motion.c +++ b/contrib/gcc-8.0/gcc/store-motion.c @@ -912,8 +912,7 @@ replace_store_insn (rtx reg, rtx_insn *del, basic_block bb, rtx_insn *insn; rtx mem, note, set; - mem = smexpr->pattern; - insn = gen_move_insn (reg, SET_SRC (single_set (del))); + insn = prepare_copy_insn (reg, SET_SRC (single_set (del))); unsigned int i; rtx_insn *temp; @@ -946,6 +945,7 @@ replace_store_insn (rtx reg, rtx_insn *del, basic_block bb, /* Now we must handle REG_EQUAL notes whose contents is equal to the mem; they are no longer accurate provided that they are reached by this definition, so drop them. */ + mem = smexpr->pattern; for (; insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn)) if (NONDEBUG_INSN_P (insn)) { diff --git a/contrib/gcc-8.0/gcc/symtab.c b/contrib/gcc-8.0/gcc/symtab.c index c153308357..67e14d76b1 100644 --- a/contrib/gcc-8.0/gcc/symtab.c +++ b/contrib/gcc-8.0/gcc/symtab.c @@ -998,6 +998,13 @@ symtab_node::verify_base (void) error ("function symbol is not function"); error_found = true; } + else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)) + != NULL) + != dyn_cast (this)->ifunc_resolver) + { + error ("inconsistent `ifunc' attribute"); + error_found = true; + } } else if (is_a (this)) { @@ -1952,11 +1959,11 @@ symtab_node::nonzero_address () return true; } - /* If target is defined and not extern, we know it will be output and thus - it will bind to non-NULL. - Play safe for flag_delete_null_pointer_checks where weak definition maye + /* If target is defined and either comdat or not extern, we know it will be + output and thus it will bind to non-NULL. + Play safe for flag_delete_null_pointer_checks where weak definition may be re-defined by NULL. */ - if (definition && !DECL_EXTERNAL (decl) + if (definition && (!DECL_EXTERNAL (decl) || DECL_COMDAT (decl)) && (flag_delete_null_pointer_checks || !DECL_WEAK (decl))) { if (!DECL_WEAK (decl)) @@ -2253,13 +2260,13 @@ symtab_node::binds_to_current_def_p (symtab_node *ref) if (transparent_alias) return definition && get_alias_target()->binds_to_current_def_p (ref); - if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + cgraph_node *cnode = dyn_cast (this); + if (cnode && cnode->ifunc_resolver) return false; if (decl_binds_to_current_def_p (decl)) return true; /* Inline clones always binds locally. */ - cgraph_node *cnode = dyn_cast (this); if (cnode && cnode->global.inlined_to) return true; diff --git a/contrib/gcc-8.0/gcc/tracer.c b/contrib/gcc-8.0/gcc/tracer.c index 58f4ec1d72..05300a289e 100644 --- a/contrib/gcc-8.0/gcc/tracer.c +++ b/contrib/gcc-8.0/gcc/tracer.c @@ -132,8 +132,7 @@ count_insns (basic_block bb) static bool better_p (const_edge e1, const_edge e2) { - if (e1->count ().initialized_p () && e2->count ().initialized_p () - && ((e1->count () > e2->count ()) || (e1->count () < e2->count ()))) + if ((e1->count () > e2->count ()) || (e1->count () < e2->count ())) return e1->count () > e2->count (); /* This is needed to avoid changes in the decision after CFG is modified. */ @@ -152,12 +151,16 @@ find_best_successor (basic_block bb) edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->succs) - if (!best || better_p (e, best)) - best = e; + { + if (!e->count ().initialized_p ()) + return NULL; + if (!best || better_p (e, best)) + best = e; + } if (!best || ignore_bb_p (best->dest)) return NULL; - if (best->probability.initialized_p () - && best->probability.to_reg_br_prob_base () <= probability_cutoff) + if (!best->probability.initialized_p () + || best->probability.to_reg_br_prob_base () <= probability_cutoff) return NULL; return best; } @@ -172,12 +175,17 @@ find_best_predecessor (basic_block bb) edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->preds) - if (!best || better_p (e, best)) - best = e; + { + if (!e->count ().initialized_p ()) + return NULL; + if (!best || better_p (e, best)) + best = e; + } if (!best || ignore_bb_p (best->src)) return NULL; - if (EDGE_FREQUENCY (best) * REG_BR_PROB_BASE - < bb->count.to_frequency (cfun) * branch_ratio_cutoff) + if (bb->count.initialized_p () + && (best->count ().to_frequency (cfun) * REG_BR_PROB_BASE + < bb->count.to_frequency (cfun) * branch_ratio_cutoff)) return NULL; return best; } diff --git a/contrib/gcc-8.0/gcc/tree-cfg.c b/contrib/gcc-8.0/gcc/tree-cfg.c index 9485f73f34..9a5edd1903 100644 --- a/contrib/gcc-8.0/gcc/tree-cfg.c +++ b/contrib/gcc-8.0/gcc/tree-cfg.c @@ -6925,7 +6925,16 @@ move_stmt_op (tree *tp, int *walk_subtrees, void *data) ; else if (block == p->orig_block || p->orig_block == NULL_TREE) - TREE_SET_BLOCK (t, p->new_block); + { + /* tree_node_can_be_shared says we can share invariant + addresses but unshare_expr copies them anyways. Make sure + to unshare before adjusting the block in place - we do not + always see a copy here. */ + if (TREE_CODE (t) == ADDR_EXPR + && is_gimple_min_invariant (t)) + *tp = t = unshare_expr (t); + TREE_SET_BLOCK (t, p->new_block); + } else if (flag_checking) { while (block && TREE_CODE (block) == BLOCK && block != p->orig_block) @@ -7278,11 +7287,14 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb, } /* Examine the statements in BB (which is in SRC_CFUN); find and return - the outermost EH region. Use REGION as the incoming base EH region. */ + the outermost EH region. Use REGION as the incoming base EH region. + If there is no single outermost region, return NULL and set *ALL to + true. */ static eh_region find_outermost_region_in_block (struct function *src_cfun, - basic_block bb, eh_region region) + basic_block bb, eh_region region, + bool *all) { gimple_stmt_iterator si; @@ -7301,7 +7313,11 @@ find_outermost_region_in_block (struct function *src_cfun, else if (stmt_region != region) { region = eh_region_outermost (src_cfun, stmt_region, region); - gcc_assert (region != NULL); + if (region == NULL) + { + *all = true; + return NULL; + } } } } @@ -7636,12 +7652,17 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, if (saved_cfun->eh) { eh_region region = NULL; + bool all = false; FOR_EACH_VEC_ELT (bbs, i, bb) - region = find_outermost_region_in_block (saved_cfun, bb, region); + { + region = find_outermost_region_in_block (saved_cfun, bb, region, &all); + if (all) + break; + } init_eh_for_function (); - if (region != NULL) + if (region != NULL || all) { new_label_map = htab_create (17, tree_map_hash, tree_map_eq, free); eh_map = duplicate_eh_regions (saved_cfun, region, 0, @@ -9288,20 +9309,16 @@ generate_range_test (basic_block bb, tree index, tree low, tree high, tree type = TREE_TYPE (index); tree utype = unsigned_type_for (type); - low = fold_convert (type, low); - high = fold_convert (type, high); - - tree tmp = make_ssa_name (type); - gassign *sub1 - = gimple_build_assign (tmp, MINUS_EXPR, index, low); + low = fold_convert (utype, low); + high = fold_convert (utype, high); - *lhs = make_ssa_name (utype); - gassign *a = gimple_build_assign (*lhs, NOP_EXPR, tmp); + gimple_seq seq = NULL; + index = gimple_convert (&seq, utype, index); + *lhs = gimple_build (&seq, MINUS_EXPR, utype, index, low); + *rhs = const_binop (MINUS_EXPR, utype, high, low); - *rhs = fold_build2 (MINUS_EXPR, utype, high, low); gimple_stmt_iterator gsi = gsi_last_bb (bb); - gsi_insert_before (&gsi, sub1, GSI_SAME_STMT); - gsi_insert_before (&gsi, a, GSI_SAME_STMT); + gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); } /* Emit return warnings. */ diff --git a/contrib/gcc-8.0/gcc/tree-chrec.c b/contrib/gcc-8.0/gcc/tree-chrec.c index 04d33ef625..896ff35784 100644 --- a/contrib/gcc-8.0/gcc/tree-chrec.c +++ b/contrib/gcc-8.0/gcc/tree-chrec.c @@ -375,10 +375,12 @@ chrec_fold_plus_1 (enum tree_code code, tree type, default: { - if (tree_contains_chrecs (op0, NULL) - || tree_contains_chrecs (op1, NULL)) + int size = 0; + if ((tree_contains_chrecs (op0, &size) + || tree_contains_chrecs (op1, &size)) + && size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE)) return build2 (code, type, op0, op1); - else + else if (size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE)) { if (code == POINTER_PLUS_EXPR) return fold_build_pointer_plus (fold_convert (type, op0), @@ -388,6 +390,8 @@ chrec_fold_plus_1 (enum tree_code code, tree type, fold_convert (type, op0), fold_convert (type, op1)); } + else + return chrec_dont_know; } } } diff --git a/contrib/gcc-8.0/gcc/tree-complex.c b/contrib/gcc-8.0/gcc/tree-complex.c index 622b869639..8707d5ef59 100644 --- a/contrib/gcc-8.0/gcc/tree-complex.c +++ b/contrib/gcc-8.0/gcc/tree-complex.c @@ -80,6 +80,9 @@ static vec complex_ssa_name_components; non-SSA_NAME/non-invariant args that need to be replaced by SSA_NAMEs. */ static vec phis_to_revisit; +/* BBs that need EH cleanup. */ +static bitmap need_eh_cleanup; + /* Lookup UID in the complex_variable_components hashtable and return the associated tree. */ static tree @@ -695,13 +698,12 @@ update_complex_components_on_edge (edge e, tree lhs, tree r, tree i) static void update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i) { - gimple *stmt; - + gimple *old_stmt = gsi_stmt (*gsi); gimple_assign_set_rhs_with_ops (gsi, COMPLEX_EXPR, r, i); - stmt = gsi_stmt (*gsi); + gimple *stmt = gsi_stmt (*gsi); update_stmt (stmt); - if (maybe_clean_eh_stmt (stmt)) - gimple_purge_dead_eh_edges (gimple_bb (stmt)); + if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) + bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index); if (gimple_in_ssa_p (cfun)) update_complex_components (gsi, gsi_stmt (*gsi), r, i); @@ -1462,6 +1464,8 @@ expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai, } update_stmt (stmt); + if (maybe_clean_eh_stmt (stmt)) + bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index); } /* Expand inline asm that sets some complex SSA_NAMEs. */ @@ -1680,6 +1684,8 @@ tree_lower_complex (void) class complex_propagate complex_propagate; complex_propagate.ssa_propagate (); + need_eh_cleanup = BITMAP_ALLOC (NULL); + complex_variable_components = new int_tree_htab_type (10); complex_ssa_name_components.create (2 * num_ssa_names); @@ -1692,6 +1698,8 @@ tree_lower_complex (void) for (i = 0; i < n_bbs; i++) { bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]); + if (!bb) + continue; update_phi_components (bb); for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) expand_complex_operations_1 (&gsi); @@ -1723,11 +1731,15 @@ tree_lower_complex (void) gsi_commit_edge_inserts (); + unsigned todo + = gimple_purge_all_dead_eh_edges (need_eh_cleanup) ? TODO_cleanup_cfg : 0; + BITMAP_FREE (need_eh_cleanup); + delete complex_variable_components; complex_variable_components = NULL; complex_ssa_name_components.release (); complex_lattice_values.release (); - return 0; + return todo; } namespace { diff --git a/contrib/gcc-8.0/gcc/tree-core.h b/contrib/gcc-8.0/gcc/tree-core.h index 478c631998..84f75e66ca 100644 --- a/contrib/gcc-8.0/gcc/tree-core.h +++ b/contrib/gcc-8.0/gcc/tree-core.h @@ -1161,6 +1161,9 @@ struct GTY(()) tree_base { OMP_CLAUSE_LINEAR_VARIABLE_STRIDE in OMP_CLAUSE_LINEAR + ASM_INLINE_P in + ASM_EXPR + side_effects_flag: TREE_SIDE_EFFECTS in @@ -1796,8 +1799,8 @@ struct GTY(()) tree_function_decl { unsigned pure_flag : 1; unsigned looping_const_or_pure_flag : 1; unsigned has_debug_args_flag : 1; - unsigned tm_clone_flag : 1; unsigned versioned_function : 1; + unsigned lambda_function: 1; /* No bits left. */ }; diff --git a/contrib/gcc-8.0/gcc/tree-data-ref.c b/contrib/gcc-8.0/gcc/tree-data-ref.c index e2107feb22..670d0de446 100644 --- a/contrib/gcc-8.0/gcc/tree-data-ref.c +++ b/contrib/gcc-8.0/gcc/tree-data-ref.c @@ -1918,6 +1918,7 @@ create_runtime_alias_checks (struct loop *loop, { tree part_cond_expr; + fold_defer_overflow_warnings (); for (size_t i = 0, s = alias_pairs->length (); i < s; ++i) { const dr_with_seg_len& dr_a = (*alias_pairs)[i].first; @@ -1940,6 +1941,7 @@ create_runtime_alias_checks (struct loop *loop, else *cond_expr = part_cond_expr; } + fold_undefer_and_ignore_overflow_warnings (); } /* Check if OFFSET1 and OFFSET2 (DR_OFFSETs of some data-refs) are identical @@ -3187,6 +3189,8 @@ initialize_matrix_A (lambda_matrix A, tree chrec, unsigned index, int mult) switch (TREE_CODE (chrec)) { case POLYNOMIAL_CHREC: + if (!cst_and_fits_in_hwi (CHREC_RIGHT (chrec))) + return chrec_dont_know; A[index][0] = mult * int_cst_value (CHREC_RIGHT (chrec)); return initialize_matrix_A (A, CHREC_LEFT (chrec), index + 1, mult); @@ -3568,7 +3572,7 @@ analyze_subscript_affine_affine (tree chrec_a, tree *last_conflicts) { unsigned nb_vars_a, nb_vars_b, dim; - HOST_WIDE_INT init_a, init_b, gamma, gcd_alpha_beta; + HOST_WIDE_INT gamma, gcd_alpha_beta; lambda_matrix A, U, S; struct obstack scratch_obstack; @@ -3605,9 +3609,20 @@ analyze_subscript_affine_affine (tree chrec_a, A = lambda_matrix_new (dim, 1, &scratch_obstack); S = lambda_matrix_new (dim, 1, &scratch_obstack); - init_a = int_cst_value (initialize_matrix_A (A, chrec_a, 0, 1)); - init_b = int_cst_value (initialize_matrix_A (A, chrec_b, nb_vars_a, -1)); - gamma = init_b - init_a; + tree init_a = initialize_matrix_A (A, chrec_a, 0, 1); + tree init_b = initialize_matrix_A (A, chrec_b, nb_vars_a, -1); + if (init_a == chrec_dont_know + || init_b == chrec_dont_know) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "affine-affine test failed: " + "representation issue.\n"); + *overlaps_a = conflict_fn_not_known (); + *overlaps_b = conflict_fn_not_known (); + *last_conflicts = chrec_dont_know; + goto end_analyze_subs_aa; + } + gamma = int_cst_value (init_b) - int_cst_value (init_a); /* Don't do all the hard work of solving the Diophantine equation when we already know the solution: for example, diff --git a/contrib/gcc-8.0/gcc/tree-dump.c b/contrib/gcc-8.0/gcc/tree-dump.c index bc3e3a9f43..fe3cc12bf2 100644 --- a/contrib/gcc-8.0/gcc/tree-dump.c +++ b/contrib/gcc-8.0/gcc/tree-dump.c @@ -683,10 +683,6 @@ dequeue_and_dump (dump_info_p di) case SWITCH_EXPR: dump_child ("cond", TREE_OPERAND (t, 0)); dump_child ("body", TREE_OPERAND (t, 1)); - if (TREE_OPERAND (t, 2)) - { - dump_child ("labl", TREE_OPERAND (t,2)); - } break; case OMP_CLAUSE: { diff --git a/contrib/gcc-8.0/gcc/tree-inline.c b/contrib/gcc-8.0/gcc/tree-inline.c index 5a0a2525c0..324c168292 100644 --- a/contrib/gcc-8.0/gcc/tree-inline.c +++ b/contrib/gcc-8.0/gcc/tree-inline.c @@ -1961,8 +1961,7 @@ copy_bb (copy_body_data *id, basic_block bb, && id->call_stmt && (decl = gimple_call_fndecl (stmt)) && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN - && ! gimple_call_va_arg_pack_p (id->call_stmt)) + && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN) { /* __builtin_va_arg_pack_len () should be replaced by the number of anonymous arguments. */ @@ -1980,10 +1979,28 @@ copy_bb (copy_body_data *id, basic_block bb, if (POINTER_BOUNDS_P (gimple_call_arg (id->call_stmt, i))) nargs--; - count = build_int_cst (integer_type_node, nargs); - new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count); - gsi_replace (©_gsi, new_stmt, false); - stmt = new_stmt; + if (!gimple_call_lhs (stmt)) + { + /* Drop unused calls. */ + gsi_remove (©_gsi, false); + continue; + } + else if (!gimple_call_va_arg_pack_p (id->call_stmt)) + { + count = build_int_cst (integer_type_node, nargs); + new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count); + gsi_replace (©_gsi, new_stmt, false); + stmt = new_stmt; + } + else if (nargs != 0) + { + tree newlhs = create_tmp_reg_or_ssa_name (integer_type_node); + count = build_int_cst (integer_type_node, nargs); + new_stmt = gimple_build_assign (gimple_call_lhs (stmt), + PLUS_EXPR, newlhs, count); + gimple_call_set_lhs (stmt, newlhs); + gsi_insert_after (©_gsi, new_stmt, GSI_NEW_STMT); + } } else if (call_stmt && id->call_stmt @@ -4132,6 +4149,9 @@ estimate_num_insns (gimple *stmt, eni_weights *weights) with very long asm statements. */ if (count > 1000) count = 1000; + /* If this asm is asm inline, count anything as minimum size. */ + if (gimple_asm_inline_p (as_a (stmt))) + count = MIN (1, count); return MAX (1, count); } @@ -4552,10 +4572,16 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) not refer to them in any way to not break GC for locations. */ if (gimple_block (stmt)) { + /* We do want to assign a not UNKNOWN_LOCATION BLOCK_SOURCE_LOCATION + to make inlined_function_outer_scope_p return true on this BLOCK. */ + location_t loc = LOCATION_LOCUS (gimple_location (stmt)); + if (loc == UNKNOWN_LOCATION) + loc = LOCATION_LOCUS (DECL_SOURCE_LOCATION (fn)); + if (loc == UNKNOWN_LOCATION) + loc = BUILTINS_LOCATION; id->block = make_node (BLOCK); BLOCK_ABSTRACT_ORIGIN (id->block) = fn; - BLOCK_SOURCE_LOCATION (id->block) - = LOCATION_LOCUS (gimple_location (stmt)); + BLOCK_SOURCE_LOCATION (id->block) = loc; prepend_lexical_block (gimple_block (stmt), id->block); } diff --git a/contrib/gcc-8.0/gcc/tree-loop-distribution.c b/contrib/gcc-8.0/gcc/tree-loop-distribution.c index 5e327f4bfd..769523ba21 100644 --- a/contrib/gcc-8.0/gcc/tree-loop-distribution.c +++ b/contrib/gcc-8.0/gcc/tree-loop-distribution.c @@ -115,6 +115,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-scalar-evolution.h" #include "params.h" #include "tree-vectorizer.h" +#include "tree-eh.h" #define MAX_DATAREFS_NUM \ @@ -997,7 +998,7 @@ generate_memset_builtin (struct loop *loop, partition *partition) /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); - nb_bytes = builtin->size; + nb_bytes = rewrite_to_non_trapping_overflow (builtin->size); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); mem = builtin->dst_base; @@ -1049,7 +1050,7 @@ generate_memcpy_builtin (struct loop *loop, partition *partition) /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); - nb_bytes = builtin->size; + nb_bytes = rewrite_to_non_trapping_overflow (builtin->size); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); dest = builtin->dst_base; @@ -1922,7 +1923,8 @@ pg_add_dependence_edges (struct graph *rdg, int dir, if (DDR_NUM_DIST_VECTS (ddr) != 1) this_dir = 2; /* If the overlap is exact preserve stmt order. */ - else if (lambda_vector_zerop (DDR_DIST_VECT (ddr, 0), 1)) + else if (lambda_vector_zerop (DDR_DIST_VECT (ddr, 0), + DDR_NB_LOOPS (ddr))) ; /* Else as the distance vector is lexicographic positive swap the dependence direction. */ diff --git a/contrib/gcc-8.0/gcc/tree-predcom.c b/contrib/gcc-8.0/gcc/tree-predcom.c index 2bde732f8a..4c0e7c7d23 100644 --- a/contrib/gcc-8.0/gcc/tree-predcom.c +++ b/contrib/gcc-8.0/gcc/tree-predcom.c @@ -2835,7 +2835,7 @@ try_combine_chains (struct loop *loop, vec *chains) return; /* Setup UID for all statements in dominance order. */ - basic_block *bbs = get_loop_body (loop); + basic_block *bbs = get_loop_body_in_dom_order (loop); renumber_gimple_stmt_uids_in_blocks (bbs, loop->num_nodes); free (bbs); diff --git a/contrib/gcc-8.0/gcc/tree-profile.c b/contrib/gcc-8.0/gcc/tree-profile.c index f96bd4b970..8f8bb4874c 100644 --- a/contrib/gcc-8.0/gcc/tree-profile.c +++ b/contrib/gcc-8.0/gcc/tree-profile.c @@ -653,7 +653,8 @@ tree_profiling (void) FOR_EACH_DEFINED_FUNCTION (node) { - if (!gimple_has_body_p (node->decl)) + bool thunk = false; + if (!gimple_has_body_p (node->decl) && !node->thunk.thunk_p) continue; /* Don't profile functions produced for builtin stuff. */ @@ -670,22 +671,43 @@ tree_profiling (void) && flag_test_coverage) continue; + if (node->thunk.thunk_p) + { + /* We can not expand variadic thunks to Gimple. */ + if (stdarg_p (TREE_TYPE (node->decl))) + continue; + thunk = true; + /* When generate profile, expand thunk to gimple so it can be + instrumented same way as other functions. */ + if (profile_arc_flag) + node->expand_thunk (false, true); + /* Read cgraph profile but keep function as thunk at profile-use + time. */ + else + { + read_thunk_profile (node); + continue; + } + } + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); if (dump_file) dump_function_header (dump_file, cfun->decl, dump_flags); /* Local pure-const may imply need to fixup the cfg. */ - if (execute_fixup_cfg () & TODO_cleanup_cfg) + if (gimple_has_body_p (node->decl) + && (execute_fixup_cfg () & TODO_cleanup_cfg)) cleanup_tree_cfg (); - branch_prob (); + branch_prob (thunk); if (! flag_branch_probabilities && flag_profile_values) gimple_gen_ic_func_profiler (); if (flag_branch_probabilities + && !thunk && flag_profile_values && flag_value_profile_transformations) gimple_value_profile_transformations (); diff --git a/contrib/gcc-8.0/gcc/tree-ssa-alias.c b/contrib/gcc-8.0/gcc/tree-ssa-alias.c index 5776687ea1..6d69e4d85f 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-alias.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-alias.c @@ -2346,7 +2346,7 @@ same_addr_size_stores_p (tree base1, poly_int64 offset1, poly_int64 size1, /* Be conservative with non-call exceptions when the address might be NULL. */ - if (flag_non_call_exceptions && pi->pt.null) + if (cfun->can_throw_non_call_exceptions && pi->pt.null) return false; /* Check that ptr points relative to obj. */ diff --git a/contrib/gcc-8.0/gcc/tree-ssa-ccp.c b/contrib/gcc-8.0/gcc/tree-ssa-ccp.c index 5591097d01..5719d6d3e2 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-ccp.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-ccp.c @@ -1120,7 +1120,7 @@ ccp_propagate::visit_phi (gphi *phi) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, - "\n Argument #%d (%d -> %d %sexecutable)\n", + "\tArgument #%d (%d -> %d %sexecutable)\n", i, e->src->index, e->dest->index, (e->flags & EDGE_EXECUTABLE) ? "" : "not "); } diff --git a/contrib/gcc-8.0/gcc/tree-ssa-coalesce.c b/contrib/gcc-8.0/gcc/tree-ssa-coalesce.c index 5cc0acad39..217a10d326 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-coalesce.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-coalesce.c @@ -1561,22 +1561,9 @@ gimple_can_coalesce_p (tree name1, tree name2) /* If the types are not the same, see whether they are compatible. This (for example) allows coalescing when the types are fundamentally the - same, but just have different names. - - In the non-optimized case, we must first test TYPE_CANONICAL because - we use it to compute the partition_to_base_index of the map. */ - if (flag_tree_coalesce_vars) - { - if (types_compatible_p (t1, t2)) - goto check_modes; - } - else - { - if (TYPE_CANONICAL (t1) - && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2) - && types_compatible_p (t1, t2)) - goto check_modes; - } + same, but just have different names. */ + if (types_compatible_p (t1, t2)) + goto check_modes; return false; } @@ -1701,89 +1688,6 @@ compute_optimized_partition_bases (var_map map, bitmap used_in_copies, partition_delete (tentative); } -/* Hashtable helpers. */ - -struct tree_int_map_hasher : nofree_ptr_hash -{ - static inline hashval_t hash (const tree_int_map *); - static inline bool equal (const tree_int_map *, const tree_int_map *); -}; - -inline hashval_t -tree_int_map_hasher::hash (const tree_int_map *v) -{ - return tree_map_base_hash (v); -} - -inline bool -tree_int_map_hasher::equal (const tree_int_map *v, const tree_int_map *c) -{ - return tree_int_map_eq (v, c); -} - -/* This routine will initialize the basevar fields of MAP with base - names. Partitions will share the same base if they have the same - SSA_NAME_VAR, or, being anonymous variables, the same type. This - must match gimple_can_coalesce_p in the non-optimized case. */ - -static void -compute_samebase_partition_bases (var_map map) -{ - int x, num_part; - tree var; - struct tree_int_map *m, *mapstorage; - - num_part = num_var_partitions (map); - hash_table tree_to_index (num_part); - /* We can have at most num_part entries in the hash tables, so it's - enough to allocate so many map elements once, saving some malloc - calls. */ - mapstorage = m = XNEWVEC (struct tree_int_map, num_part); - - /* If a base table already exists, clear it, otherwise create it. */ - free (map->partition_to_base_index); - map->partition_to_base_index = (int *) xmalloc (sizeof (int) * num_part); - - /* Build the base variable list, and point partitions at their bases. */ - for (x = 0; x < num_part; x++) - { - struct tree_int_map **slot; - unsigned baseindex; - var = partition_to_var (map, x); - if (SSA_NAME_VAR (var) - && (!VAR_P (SSA_NAME_VAR (var)) - || !DECL_IGNORED_P (SSA_NAME_VAR (var)))) - m->base.from = SSA_NAME_VAR (var); - else - /* This restricts what anonymous SSA names we can coalesce - as it restricts the sets we compute conflicts for. - Using TREE_TYPE to generate sets is the easiest as - type equivalency also holds for SSA names with the same - underlying decl. - - Check gimple_can_coalesce_p when changing this code. */ - m->base.from = (TYPE_CANONICAL (TREE_TYPE (var)) - ? TYPE_CANONICAL (TREE_TYPE (var)) - : TREE_TYPE (var)); - /* If base variable hasn't been seen, set it up. */ - slot = tree_to_index.find_slot (m, INSERT); - if (!*slot) - { - baseindex = m - mapstorage; - m->to = baseindex; - *slot = m; - m++; - } - else - baseindex = (*slot)->to; - map->partition_to_base_index[x] = baseindex; - } - - map->num_basevars = m - mapstorage; - - free (mapstorage); -} - /* Reduce the number of copies by coalescing variables in the function. Return a partition map with the resulting coalesces. */ @@ -1845,10 +1749,7 @@ coalesce_ssa_name (void) partition_view_bitmap (map, used_in_copies); - if (flag_tree_coalesce_vars) - compute_optimized_partition_bases (map, used_in_copies, cl); - else - compute_samebase_partition_bases (map); + compute_optimized_partition_bases (map, used_in_copies, cl); if (num_var_partitions (map) < 1) { diff --git a/contrib/gcc-8.0/gcc/tree-ssa-copy.c b/contrib/gcc-8.0/gcc/tree-ssa-copy.c index 0c667da2d5..b526758701 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-copy.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-copy.c @@ -155,7 +155,7 @@ set_copy_of_val (tree var, tree val) copy_of[ver].value = val; if (old != val - || (val && !operand_equal_p (old, val, 0))) + && (!old || !operand_equal_p (old, val, 0))) return true; return false; diff --git a/contrib/gcc-8.0/gcc/tree-ssa-dom.c b/contrib/gcc-8.0/gcc/tree-ssa-dom.c index a6f176c5de..f60e96cdfb 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-dom.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-dom.c @@ -776,7 +776,8 @@ pass_dominator::execute (function *fun) if (bb == NULL) continue; while (single_succ_p (bb) - && (single_succ_edge (bb)->flags & EDGE_EH) == 0) + && (single_succ_edge (bb)->flags + & (EDGE_EH|EDGE_DFS_BACK)) == 0) bb = single_succ (bb); if (bb == EXIT_BLOCK_PTR_FOR_FN (fun)) continue; diff --git a/contrib/gcc-8.0/gcc/tree-ssa-loop-ivcanon.c b/contrib/gcc-8.0/gcc/tree-ssa-loop-ivcanon.c index 24bf60eaa4..7f8b5199b6 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-loop-ivcanon.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-loop-ivcanon.c @@ -367,8 +367,8 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, size->non_call_stmts_on_hot_path++; if (((gimple_code (stmt) == GIMPLE_COND && (!constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop) - || constant_after_peeling (gimple_cond_rhs (stmt), stmt, - loop))) + || !constant_after_peeling (gimple_cond_rhs (stmt), stmt, + loop))) || (gimple_code (stmt) == GIMPLE_SWITCH && !constant_after_peeling (gimple_switch_index ( as_a (stmt)), diff --git a/contrib/gcc-8.0/gcc/tree-ssa-loop-split.c b/contrib/gcc-8.0/gcc/tree-ssa-loop-split.c index 12f6665ca4..238e0f580a 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-loop-split.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-loop-split.c @@ -649,7 +649,8 @@ tree_ssa_split_loops (void) false, true) && niter.cmp != ERROR_MARK /* We can't yet handle loops controlled by a != predicate. */ - && niter.cmp != NE_EXPR) + && niter.cmp != NE_EXPR + && can_duplicate_loop_p (loop)) { if (split_loop (loop, &niter)) { diff --git a/contrib/gcc-8.0/gcc/tree-ssa-math-opts.c b/contrib/gcc-8.0/gcc/tree-ssa-math-opts.c index 16d9399af0..8463979b4c 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-math-opts.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-math-opts.c @@ -422,6 +422,8 @@ insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ, gsi_next (&gsi); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); + if (should_insert_square_recip) + gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT); } else if (def_gsi && occ->bb == def_gsi->bb) { @@ -429,21 +431,19 @@ insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ, never happen if the definition statement can throw, because in that case the sole successor of the statement's basic block will dominate all the uses as well. */ - gsi = *def_gsi; gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT); + if (should_insert_square_recip) + gsi_insert_after (def_gsi, new_square_stmt, GSI_NEW_STMT); } else { /* Case 3: insert in a basic block not containing defs/uses. */ gsi = gsi_after_labels (occ->bb); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); + if (should_insert_square_recip) + gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT); } - /* Regardless of which case the reciprocal as inserted in, - we insert the square immediately after the reciprocal. */ - if (should_insert_square_recip) - gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT); - reciprocal_stats.rdivs_inserted++; occ->recip_def_stmt = new_stmt; diff --git a/contrib/gcc-8.0/gcc/tree-ssa-phiprop.c b/contrib/gcc-8.0/gcc/tree-ssa-phiprop.c index 03dbb390bf..14dfe2ab3b 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-phiprop.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-phiprop.c @@ -495,8 +495,14 @@ pass_phiprop::execute (function *fun) bbs = get_all_dominated_blocks (CDI_DOMINATORS, single_succ (ENTRY_BLOCK_PTR_FOR_FN (fun))); FOR_EACH_VEC_ELT (bbs, i, bb) - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - did_something |= propagate_with_phi (bb, gsi.phi (), phivn, n); + { + /* Since we're going to move dereferences across predecessor + edges avoid blocks with abnormal predecessors. */ + if (bb_has_abnormal_pred (bb)) + continue; + for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + did_something |= propagate_with_phi (bb, gsi.phi (), phivn, n); + } if (did_something) gsi_commit_edge_inserts (); diff --git a/contrib/gcc-8.0/gcc/tree-ssa-propagate.c b/contrib/gcc-8.0/gcc/tree-ssa-propagate.c index 9f67a9ab11..b1bfdd5c01 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-propagate.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-propagate.c @@ -108,51 +108,26 @@ [3] Advanced Compiler Design and Implementation, Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */ -/* Worklist of control flow edge destinations. This contains +/* Worklists of control flow edge destinations. This contains the CFG order number of the blocks so we can iterate in CFG - order by visiting in bit-order. */ + order by visiting in bit-order. We use two worklists to + first make forward progress before iterating. */ static bitmap cfg_blocks; +static bitmap cfg_blocks_back; static int *bb_to_cfg_order; static int *cfg_order_to_bb; -/* Worklist of SSA edges which will need reexamination as their +/* Worklists of SSA edges which will need reexamination as their definition has changed. SSA edges are def-use edges in the SSA web. For each D-U edge, we store the target statement or PHI node - UID in a bitmap. UIDs order stmts in execution order. */ + UID in a bitmap. UIDs order stmts in execution order. We use + two worklists to first make forward progress before iterating. */ static bitmap ssa_edge_worklist; +static bitmap ssa_edge_worklist_back; static vec uid_to_stmt; -/* Return true if the block worklist empty. */ - -static inline bool -cfg_blocks_empty_p (void) -{ - return bitmap_empty_p (cfg_blocks); -} - - -/* Add a basic block to the worklist. The block must not be the ENTRY - or EXIT block. */ - -static void -cfg_blocks_add (basic_block bb) -{ - gcc_assert (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) - && bb != EXIT_BLOCK_PTR_FOR_FN (cfun)); - bitmap_set_bit (cfg_blocks, bb_to_cfg_order[bb->index]); -} - - -/* Remove a block from the worklist. */ - -static basic_block -cfg_blocks_get (void) -{ - gcc_assert (!cfg_blocks_empty_p ()); - int order_index = bitmap_first_set_bit (cfg_blocks); - bitmap_clear_bit (cfg_blocks, order_index); - return BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb [order_index]); -} +/* Current RPO index in the iteration. */ +static int curr_order; /* We have just defined a new value for VAR. If IS_VARYING is true, @@ -168,14 +143,28 @@ add_ssa_edge (tree var) FOR_EACH_IMM_USE_FAST (use_p, iter, var) { gimple *use_stmt = USE_STMT (use_p); + if (!prop_simulate_again_p (use_stmt)) + continue; /* If we did not yet simulate the block wait for this to happen and do not add the stmt to the SSA edge worklist. */ - if (! (gimple_bb (use_stmt)->flags & BB_VISITED)) + basic_block use_bb = gimple_bb (use_stmt); + if (! (use_bb->flags & BB_VISITED)) continue; - if (prop_simulate_again_p (use_stmt) - && bitmap_set_bit (ssa_edge_worklist, gimple_uid (use_stmt))) + /* If this is a use on a not yet executable edge do not bother to + queue it. */ + if (gimple_code (use_stmt) == GIMPLE_PHI + && !(EDGE_PRED (use_bb, PHI_ARG_INDEX_FROM_USE (use_p))->flags + & EDGE_EXECUTABLE)) + continue; + + bitmap worklist; + if (bb_to_cfg_order[gimple_bb (use_stmt)->index] < curr_order) + worklist = ssa_edge_worklist_back; + else + worklist = ssa_edge_worklist; + if (bitmap_set_bit (worklist, gimple_uid (use_stmt))) { uid_to_stmt[gimple_uid (use_stmt)] = use_stmt; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -203,7 +192,11 @@ add_control_edge (edge e) e->flags |= EDGE_EXECUTABLE; - cfg_blocks_add (bb); + int bb_order = bb_to_cfg_order[bb->index]; + if (bb_order < curr_order) + bitmap_set_bit (cfg_blocks_back, bb_order); + else + bitmap_set_bit (cfg_blocks, bb_order); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Adding destination of edge (%d -> %d) to worklist\n", @@ -310,33 +303,6 @@ ssa_propagation_engine::simulate_stmt (gimple *stmt) } } -/* Process an SSA edge worklist. WORKLIST is the SSA edge worklist to - drain. This pops statements off the given WORKLIST and processes - them until one statement was simulated or there are no more statements - on WORKLIST. We take a pointer to WORKLIST because it may be reallocated - when an SSA edge is added to it in simulate_stmt. Return true if a stmt - was simulated. */ - -void -ssa_propagation_engine::process_ssa_edge_worklist (void) -{ - /* Process the next entry from the worklist. */ - unsigned stmt_uid = bitmap_first_set_bit (ssa_edge_worklist); - bitmap_clear_bit (ssa_edge_worklist, stmt_uid); - gimple *stmt = uid_to_stmt[stmt_uid]; - - /* We should not have stmts in not yet simulated BBs on the worklist. */ - gcc_assert (gimple_bb (stmt)->flags & BB_VISITED); - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "\nSimulating statement: "); - print_gimple_stmt (dump_file, stmt, 0, dump_flags); - } - - simulate_stmt (stmt); -} - /* Simulate the execution of BLOCK. Evaluate the statement associated with each variable reference inside the block. */ @@ -414,6 +380,7 @@ ssa_prop_init (void) /* Worklists of SSA edges. */ ssa_edge_worklist = BITMAP_ALLOC (NULL); + ssa_edge_worklist_back = BITMAP_ALLOC (NULL); /* Worklist of basic-blocks. */ bb_to_cfg_order = XNEWVEC (int, last_basic_block_for_fn (cfun) + 1); @@ -423,9 +390,7 @@ ssa_prop_init (void) for (int i = 0; i < n; ++i) bb_to_cfg_order[cfg_order_to_bb[i]] = i; cfg_blocks = BITMAP_ALLOC (NULL); - - if (dump_file && (dump_flags & TDF_DETAILS)) - dump_immediate_uses (dump_file); + cfg_blocks_back = BITMAP_ALLOC (NULL); /* Initially assume that every edge in the CFG is not executable. (including the edges coming out of the entry block). Mark blocks @@ -471,9 +436,11 @@ static void ssa_prop_fini (void) { BITMAP_FREE (cfg_blocks); + BITMAP_FREE (cfg_blocks_back); free (bb_to_cfg_order); free (cfg_order_to_bb); BITMAP_FREE (ssa_edge_worklist); + BITMAP_FREE (ssa_edge_worklist_back); uid_to_stmt.release (); } @@ -788,21 +755,61 @@ ssa_propagation_engine::ssa_propagate (void) { ssa_prop_init (); - /* Iterate until the worklists are empty. */ - while (! cfg_blocks_empty_p () - || ! bitmap_empty_p (ssa_edge_worklist)) + curr_order = 0; + + /* Iterate until the worklists are empty. We iterate both blocks + and stmts in RPO order, using sets of two worklists to first + complete the current iteration before iterating over backedges. */ + while (1) { - /* First simulate whole blocks. */ - if (! cfg_blocks_empty_p ()) + int next_block_order = (bitmap_empty_p (cfg_blocks) + ? -1 : bitmap_first_set_bit (cfg_blocks)); + int next_stmt_uid = (bitmap_empty_p (ssa_edge_worklist) + ? -1 : bitmap_first_set_bit (ssa_edge_worklist)); + if (next_block_order == -1 && next_stmt_uid == -1) { - /* Pull the next block to simulate off the worklist. */ - basic_block dest_block = cfg_blocks_get (); - simulate_block (dest_block); + if (bitmap_empty_p (cfg_blocks_back) + && bitmap_empty_p (ssa_edge_worklist_back)) + break; + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Regular worklists empty, now processing " + "backedge destinations\n"); + std::swap (cfg_blocks, cfg_blocks_back); + std::swap (ssa_edge_worklist, ssa_edge_worklist_back); continue; } - /* Then simulate from the SSA edge worklist. */ - process_ssa_edge_worklist (); + int next_stmt_bb_order = -1; + gimple *next_stmt = NULL; + if (next_stmt_uid != -1) + { + next_stmt = uid_to_stmt[next_stmt_uid]; + next_stmt_bb_order = bb_to_cfg_order[gimple_bb (next_stmt)->index]; + } + + /* Pull the next block to simulate off the worklist if it comes first. */ + if (next_block_order != -1 + && (next_stmt_bb_order == -1 + || next_block_order <= next_stmt_bb_order)) + { + curr_order = next_block_order; + bitmap_clear_bit (cfg_blocks, next_block_order); + basic_block bb + = BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb [next_block_order]); + simulate_block (bb); + } + /* Else simulate from the SSA edge worklist. */ + else + { + curr_order = next_stmt_bb_order; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "\nSimulating statement: "); + print_gimple_stmt (dump_file, next_stmt, 0, dump_flags); + } + simulate_stmt (next_stmt); + } } ssa_prop_fini (); diff --git a/contrib/gcc-8.0/gcc/tree-ssa-propagate.h b/contrib/gcc-8.0/gcc/tree-ssa-propagate.h index 10c48d87ff..56e1b1c137 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-propagate.h +++ b/contrib/gcc-8.0/gcc/tree-ssa-propagate.h @@ -94,9 +94,7 @@ class ssa_propagation_engine private: /* Internal implementation details. */ void simulate_stmt (gimple *stmt); - void process_ssa_edge_worklist (void); void simulate_block (basic_block); - }; class substitute_and_fold_engine diff --git a/contrib/gcc-8.0/gcc/tree-ssa-reassoc.c b/contrib/gcc-8.0/gcc/tree-ssa-reassoc.c index 38bae77ddb..91f85990b0 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-reassoc.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-reassoc.c @@ -1015,7 +1015,7 @@ eliminate_using_constants (enum tree_code opcode, fprintf (dump_file, "Found * 0, removing all other ops\n"); reassociate_stats.ops_eliminated += ops->length () - 1; - ops->truncate (1); + ops->truncate (0); ops->quick_push (oelast); return; } @@ -2168,8 +2168,13 @@ init_range_entry (struct range_entry *r, tree exp, gimple *stmt) continue; CASE_CONVERT: if (is_bool) - goto do_default; - if (TYPE_PRECISION (TREE_TYPE (arg0)) == 1) + { + if ((TYPE_PRECISION (exp_type) == 1 + || TREE_CODE (exp_type) == BOOLEAN_TYPE) + && TYPE_PRECISION (TREE_TYPE (arg0)) > 1) + return; + } + else if (TYPE_PRECISION (TREE_TYPE (arg0)) == 1) { if (TYPE_UNSIGNED (TREE_TYPE (arg0))) is_bool = true; diff --git a/contrib/gcc-8.0/gcc/tree-ssa-sccvn.c b/contrib/gcc-8.0/gcc/tree-ssa-sccvn.c index 1463c1d411..6766fc58bf 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-sccvn.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-sccvn.c @@ -1650,7 +1650,6 @@ vn_reference_lookup_or_insert_for_pieces (tree vuse, } static vn_nary_op_t vn_nary_op_insert_stmt (gimple *stmt, tree result); -static unsigned mprts_hook_cnt; /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */ @@ -1672,22 +1671,8 @@ vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops_) ops[i] = CONSTRUCTOR_ELT (ops_[0], i)->value; } vn_nary_op_t vnresult = NULL; - tree res = vn_nary_op_lookup_pieces (length, (tree_code) rcode, - type, ops, &vnresult); - /* We can end up endlessly recursing simplifications if the lookup above - presents us with a def-use chain that mirrors the original simplification. - See PR80887 for an example. Limit successful lookup artificially - to 10 times if we are called as mprts_hook. */ - if (res - && mprts_hook - && --mprts_hook_cnt == 0) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Resetting mprts_hook after too many " - "invocations.\n"); - mprts_hook = NULL; - } - return res; + return vn_nary_op_lookup_pieces (length, (tree_code) rcode, + type, ops, &vnresult); } /* Return a value-number for RCODE OPS... either by looking up an existing @@ -1704,7 +1689,6 @@ vn_nary_build_or_lookup_1 (code_helper rcode, tree type, tree *ops, So first simplify and lookup this expression to see if it is already available. */ mprts_hook = vn_lookup_simplify_result; - mprts_hook_cnt = 9; bool res = false; switch (TREE_CODE_LENGTH ((tree_code) rcode)) { @@ -1880,7 +1864,16 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, VN_WALKREWRITE guard). */ if (vn_walk_kind == VN_WALKREWRITE && is_gimple_reg_type (TREE_TYPE (lhs)) - && types_compatible_p (TREE_TYPE (lhs), vr->type)) + && types_compatible_p (TREE_TYPE (lhs), vr->type) + /* The overlap restriction breaks down when either access + alias-set is zero. Still for accesses of the size of + an addressable unit there can be no overlaps. Overlaps + between different union members are not an issue since + activation of a union member via a store makes the + values of untouched bytes unspecified. */ + && (known_eq (ref->size, BITS_PER_UNIT) + || (get_alias_set (lhs) != 0 + && ao_ref_alias_set (ref) != 0))) { tree *saved_last_vuse_ptr = last_vuse_ptr; /* Do not update last_vuse_ptr in vn_reference_lookup_2. */ @@ -1992,6 +1985,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), &offset2, &size2, &maxsize2, &reverse); if (known_size_p (maxsize2) + && known_eq (maxsize2, size2) && operand_equal_p (base, base2, 0) && known_subrange_p (offset, maxsize, offset2, size2)) { @@ -2085,6 +2079,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), &offset2, &size2, &maxsize2, &reverse); + tree def_rhs = gimple_assign_rhs1 (def_stmt); if (!reverse && known_size_p (maxsize2) && known_eq (maxsize2, size2) @@ -2096,11 +2091,13 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, according to endianness. */ && (! INTEGRAL_TYPE_P (vr->type) || known_eq (ref->size, TYPE_PRECISION (vr->type))) - && multiple_p (ref->size, BITS_PER_UNIT)) + && multiple_p (ref->size, BITS_PER_UNIT) + && (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs)) + || type_has_mode_precision_p (TREE_TYPE (def_rhs)))) { code_helper rcode = BIT_FIELD_REF; tree ops[3]; - ops[0] = SSA_VAL (gimple_assign_rhs1 (def_stmt)); + ops[0] = SSA_VAL (def_rhs); ops[1] = bitsize_int (ref->size); ops[2] = bitsize_int (offset - offset2); tree val = vn_nary_build_or_lookup (rcode, vr->type, ops); @@ -3622,7 +3619,17 @@ visit_nary_op (tree lhs, gassign *stmt) ops[0] = vn_nary_op_lookup_pieces (2, gimple_assign_rhs_code (def), type, ops, NULL); /* We have wider operation available. */ - if (ops[0]) + if (ops[0] + /* If the leader is a wrapping operation we can + insert it for code hoisting w/o introducing + undefined overflow. If it is not it has to + be available. See PR86554. */ + && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (ops[0])) + || TREE_CODE (ops[0]) != SSA_NAME + || SSA_NAME_IS_DEFAULT_DEF (ops[0]) + || dominated_by_p_w_unex + (gimple_bb (stmt), + gimple_bb (SSA_NAME_DEF_STMT (ops[0]))))) { unsigned lhs_prec = TYPE_PRECISION (type); unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1)); @@ -3979,7 +3986,6 @@ try_to_simplify (gassign *stmt) /* First try constant folding based on our current lattice. */ mprts_hook = vn_lookup_simplify_result; - mprts_hook_cnt = 9; tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize); mprts_hook = NULL; if (tem diff --git a/contrib/gcc-8.0/gcc/tree-ssa-strlen.c b/contrib/gcc-8.0/gcc/tree-ssa-strlen.c index 33004b6870..50b0724ab3 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-strlen.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-strlen.c @@ -795,9 +795,9 @@ get_stridx_plus_constant (strinfo *basesi, unsigned HOST_WIDE_INT off, si = new_strinfo (ptr, idx, build_int_cst (size_type_node, nonzero_chars), basesi->full_string_p); set_strinfo (idx, si); - if (chainsi->next) + if (strinfo *nextsi = get_strinfo (chainsi->next)) { - strinfo *nextsi = unshare_strinfo (get_strinfo (chainsi->next)); + nextsi = unshare_strinfo (nextsi); si->next = nextsi->idx; nextsi->prev = idx; } @@ -1156,14 +1156,15 @@ adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat) update_stmt (last.stmt); } -/* For an LHS that is an SSA_NAME and for strlen() argument SRC, set - LHS range info to [0, N] if SRC refers to a character array A[N] - with unknown length bounded by N. */ +/* For an LHS that is an SSA_NAME with integer type and for strlen() + argument SRC, set LHS range info to [0, N] if SRC refers to + a character array A[N] with unknown length bounded by N. */ static void maybe_set_strlen_range (tree lhs, tree src) { - if (TREE_CODE (lhs) != SSA_NAME) + if (TREE_CODE (lhs) != SSA_NAME + || !INTEGRAL_TYPE_P (TREE_TYPE (lhs))) return; if (TREE_CODE (src) == SSA_NAME) @@ -1181,15 +1182,18 @@ maybe_set_strlen_range (tree lhs, tree src) suggests if it's treated as a poor-man's flexible array member. */ src = TREE_OPERAND (src, 0); if (TREE_CODE (TREE_TYPE (src)) != ARRAY_TYPE + || TREE_CODE (src) == MEM_REF || array_at_struct_end_p (src)) return; tree type = TREE_TYPE (src); - if (tree dom = TYPE_DOMAIN (type)) - if (tree maxval = TYPE_MAX_VALUE (dom)) + if (tree size = TYPE_SIZE_UNIT (type)) + if (size && TREE_CODE (size) == INTEGER_CST) { - wide_int max = wi::to_wide (maxval); + wide_int max = wi::to_wide (size); wide_int min = wi::zero (max.get_precision ()); + if (max != 0) + --max; set_range_info (lhs, VR_RANGE, min, max); } } @@ -1735,7 +1739,7 @@ handle_builtin_strncat (built_in_function bcode, gimple_stmt_iterator *gsi) assumed to be the argument in some call to strlen() whose relationship to SRC is being ascertained. */ -static bool +bool is_strlen_related_p (tree src, tree len) { if (TREE_CODE (TREE_TYPE (len)) == POINTER_TYPE @@ -1772,12 +1776,20 @@ is_strlen_related_p (tree src, tree len) && (code == BIT_AND_EXPR || code == NOP_EXPR))) { - /* Pointer plus (an integer) and integer cast or truncation are - considered among the (potentially) related expressions to strlen. - Others are not. */ + /* Pointer plus (an integer), and truncation are considered among + the (potentially) related expressions to strlen. */ return is_strlen_related_p (src, rhs1); } + if (tree rhs2 = gimple_assign_rhs2 (def_stmt)) + { + /* Integer subtraction is considered strlen-related when both + arguments are integers and second one is strlen-related. */ + rhstype = TREE_TYPE (rhs2); + if (INTEGRAL_TYPE_P (rhstype) && code == MINUS_EXPR) + return is_strlen_related_p (src, rhs2); + } + return false; } @@ -1848,9 +1860,22 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) if (TREE_CODE (dstdecl) == ADDR_EXPR) dstdecl = TREE_OPERAND (dstdecl, 0); - /* If the destination refers to a an array/pointer declared nonstring - return early. */ tree ref = NULL_TREE; + + if (!sidx) + { + /* If the source is a non-string return early to avoid warning + for possible truncation (if the truncation is certain SIDX + is non-zero). */ + tree srcdecl = gimple_call_arg (stmt, 1); + if (TREE_CODE (srcdecl) == ADDR_EXPR) + srcdecl = TREE_OPERAND (srcdecl, 0); + if (get_attr_nonstring_decl (srcdecl, &ref)) + return false; + } + + /* Likewise, if the destination refers to a an array/pointer declared + nonstring return early. */ if (get_attr_nonstring_decl (dstdecl, &ref)) return false; diff --git a/contrib/gcc-8.0/gcc/tree-ssa-strlen.h b/contrib/gcc-8.0/gcc/tree-ssa-strlen.h index 1399a7819e..f427fb741a 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-strlen.h +++ b/contrib/gcc-8.0/gcc/tree-ssa-strlen.h @@ -21,6 +21,7 @@ #ifndef GCC_TREE_SSA_STRLEN_H #define GCC_TREE_SSA_STRLEN_H +extern bool is_strlen_related_p (tree, tree); extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree); #endif // GCC_TREE_SSA_STRLEN_H diff --git a/contrib/gcc-8.0/gcc/tree-ssa-structalias.c b/contrib/gcc-8.0/gcc/tree-ssa-structalias.c index d3b38c3eaf..373946f518 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-structalias.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-structalias.c @@ -6385,7 +6385,7 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt, && bitmap_bit_p (escaped_vi->solution, i))) { pt->vars_contains_escaped = true; - pt->vars_contains_escaped_heap = vi->is_heap_var; + pt->vars_contains_escaped_heap |= vi->is_heap_var; } if (vi->is_restrict_var) @@ -7370,6 +7370,7 @@ delete_points_to_sets (void) struct vls_data { unsigned short clique; + bool escaped_p; bitmap rvars; }; @@ -7381,6 +7382,7 @@ visit_loadstore (gimple *, tree base, tree ref, void *data) { unsigned short clique = ((vls_data *) data)->clique; bitmap rvars = ((vls_data *) data)->rvars; + bool escaped_p = ((vls_data *) data)->escaped_p; if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF) { @@ -7401,7 +7403,8 @@ visit_loadstore (gimple *, tree base, tree ref, void *data) return false; vi = get_varinfo (find (vi->id)); - if (bitmap_intersect_p (rvars, vi->solution)) + if (bitmap_intersect_p (rvars, vi->solution) + || (escaped_p && bitmap_bit_p (vi->solution, escaped_id))) return false; } @@ -7478,6 +7481,7 @@ compute_dependence_clique (void) unsigned short clique = 0; unsigned short last_ruid = 0; bitmap rvars = BITMAP_ALLOC (NULL); + bool escaped_p = false; for (unsigned i = 0; i < num_ssa_names; ++i) { tree ptr = ssa_name (i); @@ -7547,7 +7551,12 @@ compute_dependence_clique (void) last_ruid); } if (used) - bitmap_set_bit (rvars, restrict_var->id); + { + bitmap_set_bit (rvars, restrict_var->id); + varinfo_t escaped = get_varinfo (find (escaped_id)); + if (bitmap_bit_p (escaped->solution, restrict_var->id)) + escaped_p = true; + } } } @@ -7560,7 +7569,7 @@ compute_dependence_clique (void) parameters) we can't restrict scoping properly thus the following is too aggressive there. For now we have excluded those globals from getting into the MR_DEPENDENCE machinery. */ - vls_data data = { clique, rvars }; + vls_data data = { clique, escaped_p, rvars }; basic_block bb; FOR_EACH_BB_FN (bb, cfun) for (gimple_stmt_iterator gsi = gsi_start_bb (bb); diff --git a/contrib/gcc-8.0/gcc/tree-ssa-tail-merge.c b/contrib/gcc-8.0/gcc/tree-ssa-tail-merge.c index f482ce197c..837679a637 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-tail-merge.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-tail-merge.c @@ -286,6 +286,21 @@ struct aux_bb_info #define BB_VOP_AT_EXIT(bb) (((struct aux_bb_info *)bb->aux)->vop_at_exit) #define BB_DEP_BB(bb) (((struct aux_bb_info *)bb->aux)->dep_bb) +/* Valueization helper querying the VN lattice. */ + +static tree +tail_merge_valueize (tree name) +{ + if (TREE_CODE (name) == SSA_NAME + && has_VN_INFO (name)) + { + tree tem = VN_INFO (name)->valnum; + if (tem != VN_TOP) + return tem; + } + return name; +} + /* Returns true if the only effect a statement STMT has, is to define locally used SSA_NAMEs. */ @@ -301,7 +316,15 @@ stmt_local_def (gimple *stmt) if (gimple_vdef (stmt) != NULL_TREE || gimple_has_side_effects (stmt) || gimple_could_trap_p_1 (stmt, false, false) - || gimple_vuse (stmt) != NULL_TREE) + || gimple_vuse (stmt) != NULL_TREE + /* Copied from tree-ssa-ifcombine.c:bb_no_side_effects_p(): + const calls don't match any of the above, yet they could + still have some side-effects - they could contain + gimple_could_trap_p statements, like floating point + exceptions or integer division by zero. See PR70586. + FIXME: perhaps gimple_has_side_effects or gimple_could_trap_p + should handle this. */ + || is_gimple_call (stmt)) return false; def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF); @@ -363,7 +386,7 @@ gvn_uses_equal (tree val1, tree val2) if (val1 == val2) return true; - if (vn_valueize (val1) != vn_valueize (val2)) + if (tail_merge_valueize (val1) != tail_merge_valueize (val2)) return false; return ((TREE_CODE (val1) == SSA_NAME || CONSTANT_CLASS_P (val1)) @@ -473,7 +496,7 @@ same_succ_hash (const same_succ *e) for (i = 0; i < gimple_call_num_args (stmt); i++) { arg = gimple_call_arg (stmt, i); - arg = vn_valueize (arg); + arg = tail_merge_valueize (arg); inchash::add_expr (arg, hstate); } } @@ -1139,7 +1162,7 @@ gimple_equal_p (same_succ *same_succ, gimple *s1, gimple *s2) if (lhs1 == NULL_TREE || lhs2 == NULL_TREE) return false; if (TREE_CODE (lhs1) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME) - return vn_valueize (lhs1) == vn_valueize (lhs2); + return tail_merge_valueize (lhs1) == tail_merge_valueize (lhs2); return operand_equal_p (lhs1, lhs2, 0); case GIMPLE_ASSIGN: diff --git a/contrib/gcc-8.0/gcc/tree-ssa-threadupdate.c b/contrib/gcc-8.0/gcc/tree-ssa-threadupdate.c index 9ab9e7d7d9..b6bc5fcf17 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-threadupdate.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-threadupdate.c @@ -1309,7 +1309,9 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) and thread this elsewhere, so just cancel the jump threading request by clearing the AUX field now. */ if (bb->loop_father != e2->src->loop_father - && !loop_exit_edge_p (e2->src->loop_father, e2)) + && (!loop_exit_edge_p (e2->src->loop_father, e2) + || flow_loop_nested_p (bb->loop_father, + e2->dest->loop_father))) { /* Since this case is not handled by our special code to thread through a loop header, we must explicitly diff --git a/contrib/gcc-8.0/gcc/tree-ssa-uncprop.c b/contrib/gcc-8.0/gcc/tree-ssa-uncprop.c index 7d863a7155..f048fe69c7 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa-uncprop.c +++ b/contrib/gcc-8.0/gcc/tree-ssa-uncprop.c @@ -268,21 +268,24 @@ associate_equivalences_with_edges (void) so with each value we have a list of SSA_NAMEs that have the same value. */ - -/* Main structure for recording equivalences into our hash table. */ -struct equiv_hash_elt +/* Traits for the hash_map to record the value to SSA name equivalences + mapping. */ +struct ssa_equip_hash_traits : default_hash_traits { - /* The value/key of this entry. */ - tree value; - - /* List of SSA_NAMEs which have the same value/key. */ - vec equivalences; + static inline hashval_t hash (value_type value) + { return iterative_hash_expr (value, 0); } + static inline bool equal (value_type existing, value_type candidate) + { return operand_equal_p (existing, candidate, 0); } }; +typedef hash_map, + simple_hashmap_traits > > val_ssa_equiv_t; + /* Global hash table implementing a mapping from invariant values to a list of SSA_NAMEs which have the same value. We might be able to reuse tree-vn for this code. */ -static hash_map > *val_ssa_equiv; +val_ssa_equiv_t *val_ssa_equiv; static void uncprop_into_successor_phis (basic_block); @@ -476,7 +479,7 @@ pass_uncprop::execute (function *fun) associate_equivalences_with_edges (); /* Create our global data structures. */ - val_ssa_equiv = new hash_map > (1024); + val_ssa_equiv = new val_ssa_equiv_t (1024); /* We're going to do a dominator walk, so ensure that we have dominance information. */ diff --git a/contrib/gcc-8.0/gcc/tree-ssa.c b/contrib/gcc-8.0/gcc/tree-ssa.c index d197f99bdd..711377c522 100644 --- a/contrib/gcc-8.0/gcc/tree-ssa.c +++ b/contrib/gcc-8.0/gcc/tree-ssa.c @@ -1446,6 +1446,7 @@ non_rewritable_mem_ref_base (tree ref) return NULL_TREE; /* For integral typed extracts we can use a BIT_FIELD_REF. */ if (DECL_SIZE (decl) + && TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST && (known_subrange_p (mem_ref_offset (base), wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (base))), diff --git a/contrib/gcc-8.0/gcc/tree-streamer-in.c b/contrib/gcc-8.0/gcc/tree-streamer-in.c index 912fa5f0f0..f391174056 100644 --- a/contrib/gcc-8.0/gcc/tree-streamer-in.c +++ b/contrib/gcc-8.0/gcc/tree-streamer-in.c @@ -159,6 +159,11 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1); bp_unpack_value (bp, 8); } + else if (TREE_CODE (expr) == CALL_EXPR) + { + CALL_EXPR_BY_DESCRIPTOR (expr) = (unsigned) bp_unpack_value (bp, 1); + bp_unpack_value (bp, 8); + } else bp_unpack_value (bp, 9); } @@ -522,6 +527,8 @@ streamer_read_tree_bitfields (struct lto_input_block *ib, MR_DEPENDENCE_BASE (expr) = (unsigned)bp_unpack_value (&bp, sizeof (short) * 8); } + else if (code == CALL_EXPR) + CALL_EXPR_IFN (expr) = bp_unpack_enum (&bp, internal_fn, IFN_LAST); } if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) diff --git a/contrib/gcc-8.0/gcc/tree-streamer-out.c b/contrib/gcc-8.0/gcc/tree-streamer-out.c index 03145b4cf5..ba89f841b5 100644 --- a/contrib/gcc-8.0/gcc/tree-streamer-out.c +++ b/contrib/gcc-8.0/gcc/tree-streamer-out.c @@ -129,6 +129,11 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1); bp_pack_value (bp, 0, 8); } + else if (TREE_CODE (expr) == CALL_EXPR) + { + bp_pack_value (bp, CALL_EXPR_BY_DESCRIPTOR (expr), 1); + bp_pack_value (bp, 0, 8); + } else bp_pack_value (bp, 0, 9); } @@ -457,6 +462,8 @@ streamer_write_tree_bitfields (struct output_block *ob, tree expr) if (MR_DEPENDENCE_CLIQUE (expr) != 0) bp_pack_value (&bp, MR_DEPENDENCE_BASE (expr), sizeof (short) * 8); } + else if (code == CALL_EXPR) + bp_pack_enum (&bp, internal_fn, IFN_LAST, CALL_EXPR_IFN (expr)); } if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) @@ -603,7 +610,16 @@ write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr, special handling in LTO, it must be handled by streamer hooks. */ stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p); - stream_write_tree (ob, DECL_ABSTRACT_ORIGIN (expr), ref_p); + + /* On non-early-LTO enabled targets we claim we compiled with -g0 + but dwarf2out still did its set_decl_origin_self game fooling + itself late. Und that here since we won't have access to the + early generated abstract DIEs. */ + tree ao = DECL_ABSTRACT_ORIGIN (expr); + if (debug_info_level == DINFO_LEVEL_NONE + && ao == expr) + ao = NULL_TREE; + stream_write_tree (ob, ao, ref_p); if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL) && DECL_HAS_VALUE_EXPR_P (expr)) diff --git a/contrib/gcc-8.0/gcc/tree-switch-conversion.c b/contrib/gcc-8.0/gcc/tree-switch-conversion.c index b0470ef1b5..4aaffb38b2 100644 --- a/contrib/gcc-8.0/gcc/tree-switch-conversion.c +++ b/contrib/gcc-8.0/gcc/tree-switch-conversion.c @@ -1690,7 +1690,7 @@ typedef case_node *case_node_ptr; static basic_block emit_case_nodes (basic_block, tree, case_node_ptr, basic_block, tree, profile_probability, - tree, hash_map *); + tree, hash_map *, location_t); static bool node_has_low_bound (case_node_ptr, tree); static bool node_has_high_bound (case_node_ptr, tree); static bool node_is_bounded (case_node_ptr, tree); @@ -1996,7 +1996,8 @@ emit_case_decision_tree (gswitch *s, tree index_expr, tree index_type, bb = split_edge (e); bb = emit_case_nodes (bb, index_expr, case_list, default_bb, default_label, - default_prob, index_type, phi_mapping); + default_prob, index_type, phi_mapping, + gimple_location (s)); if (bb) emit_jump (bb, default_bb, phi_mapping); @@ -2243,9 +2244,11 @@ make_pass_lower_switch (gcc::context *ctxt) PROB is the probability of jumping to LABEL. */ static basic_block do_jump_if_equal (basic_block bb, tree op0, tree op1, basic_block label_bb, - profile_probability prob, hash_map *phi_mapping) + profile_probability prob, hash_map *phi_mapping, + location_t loc) { gcond *cond = gimple_build_cond (EQ_EXPR, op0, op1, NULL_TREE, NULL_TREE); + gimple_set_location (cond, loc); gimple_stmt_iterator gsi = gsi_last_bb (bb); gsi_insert_before (&gsi, cond, GSI_SAME_STMT); @@ -2286,9 +2289,11 @@ static basic_block emit_cmp_and_jump_insns (basic_block bb, tree op0, tree op1, tree_code comparison, basic_block label_bb, profile_probability prob, - hash_map *phi_mapping) + hash_map *phi_mapping, + location_t loc) { gcond *cond = gimple_build_cond (comparison, op0, op1, NULL_TREE, NULL_TREE); + gimple_set_location (cond, loc); gimple_stmt_iterator gsi = gsi_last_bb (bb); gsi_insert_after (&gsi, cond, GSI_NEW_STMT); @@ -2350,7 +2355,8 @@ static basic_block emit_case_nodes (basic_block bb, tree index, case_node_ptr node, basic_block default_bb, tree default_label, profile_probability default_prob, tree index_type, - hash_map *phi_mapping) + hash_map *phi_mapping, + location_t loc) { /* If INDEX has an unsigned type, we must make unsigned branches. */ profile_probability probability; @@ -2370,7 +2376,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, /* Node is single valued. First see if the index expression matches this node and then check our children, if any. */ bb = do_jump_if_equal (bb, index, node->low, node->case_bb, probability, - phi_mapping); + phi_mapping, loc); /* Since this case is taken at this point, reduce its weight from subtree_weight. */ subtree_prob -= prob; @@ -2389,10 +2395,10 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, GT_EXPR, node->right->case_bb, probability, - phi_mapping); + phi_mapping, loc); bb = emit_case_nodes (bb, index, node->left, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } else if (node_is_bounded (node->left, index_type)) @@ -2402,10 +2408,10 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, LT_EXPR, node->left->case_bb, probability, - phi_mapping); + phi_mapping, loc); bb = emit_case_nodes (bb, index, node->right, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } /* If both children are single-valued cases with no @@ -2426,7 +2432,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = do_jump_if_equal (bb, index, node->right->low, node->right->case_bb, probability, - phi_mapping); + phi_mapping, loc); /* See if the value matches what the left hand side wants. */ @@ -2435,7 +2441,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = do_jump_if_equal (bb, index, node->left->low, node->left->case_bb, probability, - phi_mapping); + phi_mapping, loc); } else @@ -2456,14 +2462,15 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); /* See if the value is on the right. */ bb = emit_cmp_and_jump_insns (bb, index, node->high, GT_EXPR, - test_bb, probability, phi_mapping); + test_bb, probability, phi_mapping, + loc); default_prob = default_prob.apply_scale (1, 2); /* Value must be on the left. Handle the left-hand subtree. */ bb = emit_case_nodes (bb, index, node->left, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); /* If left-hand subtree does nothing, go to default. */ @@ -2473,7 +2480,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, /* Code branches here for the right-hand subtree. */ bb = emit_case_nodes (test_bb, index, node->right, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } } else if (node->right != 0 && node->left == 0) @@ -2495,13 +2502,13 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, LT_EXPR, default_bb, probability, - phi_mapping); + phi_mapping, loc); default_prob = default_prob.apply_scale (1, 2); } bb = emit_case_nodes (bb, index, node->right, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } else { @@ -2513,7 +2520,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, this node's value. So handle node->right explicitly. */ bb = do_jump_if_equal (bb, index, node->right->low, node->right->case_bb, probability, - phi_mapping); + phi_mapping, loc); } } @@ -2530,13 +2537,13 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, GT_EXPR, default_bb, probability, - phi_mapping); + phi_mapping, loc); default_prob = default_prob.apply_scale (1, 2); } bb = emit_case_nodes (bb, index, node->left, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } else { @@ -2547,7 +2554,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, since we haven't ruled out the numbers less than this node's value. So handle node->left explicitly. */ do_jump_if_equal (bb, index, node->left->low, node->left->case_bb, - probability, phi_mapping); + probability, phi_mapping, loc); } } } @@ -2575,7 +2582,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, GT_EXPR, node->right->case_bb, probability, - phi_mapping); + phi_mapping, loc); } else { @@ -2591,7 +2598,8 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, + default_prob.apply_scale (1, 2), subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, GT_EXPR, - test_bb, probability, phi_mapping); + test_bb, probability, phi_mapping, + loc); default_prob = default_prob.apply_scale (1, 2); } @@ -2601,12 +2609,12 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, = conditional_probability (prob, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->low, GE_EXPR, node->case_bb, probability, - phi_mapping); + phi_mapping, loc); /* Handle the left-hand subtree. */ bb = emit_case_nodes (bb, index, node->left, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); /* If right node had to be handled later, do that now. */ if (test_bb) @@ -2618,7 +2626,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, bb = emit_case_nodes (test_bb, index, node->right, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } } @@ -2633,7 +2641,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->low, LT_EXPR, default_bb, probability, - phi_mapping); + phi_mapping, loc); default_prob = default_prob.apply_scale (1, 2); } @@ -2643,11 +2651,11 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, = conditional_probability (prob, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, LE_EXPR, node->case_bb, probability, - phi_mapping); + phi_mapping, loc); bb = emit_case_nodes (bb, index, node->right, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } else if (node->right == 0 && node->left != 0) @@ -2661,7 +2669,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, GT_EXPR, default_bb, probability, - phi_mapping); + phi_mapping, loc); default_prob = default_prob.apply_scale (1, 2); } @@ -2671,11 +2679,11 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, = conditional_probability (prob, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->low, GE_EXPR, node->case_bb, probability, - phi_mapping); + phi_mapping, loc); bb = emit_case_nodes (bb, index, node->left, default_bb, default_label, default_prob, index_type, - phi_mapping); + phi_mapping, loc); } else @@ -2693,7 +2701,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->high, GT_EXPR, default_bb, probability, - phi_mapping); + phi_mapping, loc); } else if (!low_bound && high_bound) @@ -2703,7 +2711,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->low, LT_EXPR, default_bb, probability, - phi_mapping); + phi_mapping, loc); } else if (!low_bound && !high_bound) { @@ -2715,7 +2723,7 @@ emit_case_nodes (basic_block bb, tree index, case_node_ptr node, subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, lhs, rhs, GT_EXPR, default_bb, probability, - phi_mapping); + phi_mapping, loc); } emit_jump (bb, node->case_bb, phi_mapping); diff --git a/contrib/gcc-8.0/gcc/tree-vect-data-refs.c b/contrib/gcc-8.0/gcc/tree-vect-data-refs.c index 1c27c5034c..68f8027583 100644 --- a/contrib/gcc-8.0/gcc/tree-vect-data-refs.c +++ b/contrib/gcc-8.0/gcc/tree-vect-data-refs.c @@ -206,14 +206,26 @@ vect_preserves_scalar_order_p (gimple *stmt_a, gimple *stmt_b) return true; /* STMT_A and STMT_B belong to overlapping groups. All loads in a - group are emitted at the position of the first scalar load and all + group are emitted at the position of the last scalar load and all stores in a group are emitted at the position of the last scalar store. - Thus writes will happen no earlier than their current position - (but could happen later) while reads will happen no later than their - current position (but could happen earlier). Reordering is therefore - only possible if the first access is a write. */ - gimple *earlier_stmt = get_earlier_stmt (stmt_a, stmt_b); - return !DR_IS_WRITE (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))); + Compute that position and check whether the resulting order matches + the current one. */ + gimple *last_a = GROUP_FIRST_ELEMENT (stmtinfo_a); + if (last_a) + for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_a)); s; + s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s))) + last_a = get_later_stmt (last_a, s); + else + last_a = stmt_a; + gimple *last_b = GROUP_FIRST_ELEMENT (stmtinfo_b); + if (last_b) + for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_b)); s; + s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s))) + last_b = get_later_stmt (last_b, s); + else + last_b = stmt_b; + return ((get_later_stmt (last_a, last_b) == last_a) + == (get_later_stmt (stmt_a, stmt_b) == stmt_a)); } /* A subroutine of vect_analyze_data_ref_dependence. Handle diff --git a/contrib/gcc-8.0/gcc/tree-vect-generic.c b/contrib/gcc-8.0/gcc/tree-vect-generic.c index 3dcbdeba95..9d6338371e 100644 --- a/contrib/gcc-8.0/gcc/tree-vect-generic.c +++ b/contrib/gcc-8.0/gcc/tree-vect-generic.c @@ -111,12 +111,8 @@ build_word_mode_vector_type (int nunits) return vector_last_type; } - /* We build a new type, but we canonicalize it nevertheless, - because it still saves some memory. */ vector_last_nunits = nunits; - vector_last_type = type_hash_canon (nunits, - build_vector_type (vector_inner_type, - nunits)); + vector_last_type = build_vector_type (vector_inner_type, nunits); return vector_last_type; } @@ -1612,6 +1608,12 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi) if (!VECTOR_TYPE_P (type) || !VECTOR_TYPE_P (TREE_TYPE (rhs1))) return; + + /* A scalar operation pretending to be a vector one. */ + if (VECTOR_BOOLEAN_TYPE_P (type) + && !VECTOR_MODE_P (TYPE_MODE (type)) + && TYPE_MODE (type) != BLKmode) + return; /* If the vector operation is operating on all same vector elements implement it with a scalar operation and a splat if the target @@ -1638,12 +1640,6 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi) return; } } - - /* A scalar operation pretending to be a vector one. */ - if (VECTOR_BOOLEAN_TYPE_P (type) - && !VECTOR_MODE_P (TYPE_MODE (type)) - && TYPE_MODE (type) != BLKmode) - return; if (CONVERT_EXPR_CODE_P (code) || code == FLOAT_EXPR diff --git a/contrib/gcc-8.0/gcc/tree-vect-loop.c b/contrib/gcc-8.0/gcc/tree-vect-loop.c index 4ce721ed47..c74a485cc2 100644 --- a/contrib/gcc-8.0/gcc/tree-vect-loop.c +++ b/contrib/gcc-8.0/gcc/tree-vect-loop.c @@ -2391,14 +2391,22 @@ start_over: /* The main loop handles all iterations. */ LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) = false; else if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) - && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) > 0) + && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) >= 0) { - if (!multiple_p (LOOP_VINFO_INT_NITERS (loop_vinfo) - - LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo), + /* Work out the (constant) number of iterations that need to be + peeled for reasons other than niters. */ + unsigned int peel_niter = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo); + if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)) + peel_niter += 1; + if (!multiple_p (LOOP_VINFO_INT_NITERS (loop_vinfo) - peel_niter, LOOP_VINFO_VECT_FACTOR (loop_vinfo))) LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) = true; } else if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) + /* ??? When peeling for gaps but not alignment, we could + try to check whether the (variable) niters is known to be + VF * N + 1. That's something of a niche case though. */ + || LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) || !LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant (&const_vf) || ((tree_ctz (LOOP_VINFO_NITERS (loop_vinfo)) < (unsigned) exact_log2 (const_vf)) @@ -2805,8 +2813,8 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi, struct loop *loop = (gimple_bb (phi))->loop_father; struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); enum tree_code code; - gimple *current_stmt = NULL, *loop_use_stmt = NULL, *first, *next_stmt; - stmt_vec_info use_stmt_info, current_stmt_info; + gimple *loop_use_stmt = NULL; + stmt_vec_info use_stmt_info; tree lhs; imm_use_iterator imm_iter; use_operand_p use_p; @@ -2816,6 +2824,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi, if (loop != vect_loop) return false; + auto_vec reduc_chain; lhs = PHI_RESULT (phi); code = gimple_assign_rhs_code (first_stmt); while (1) @@ -2868,18 +2877,9 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi, /* Insert USE_STMT into reduction chain. */ use_stmt_info = vinfo_for_stmt (loop_use_stmt); - if (current_stmt) - { - current_stmt_info = vinfo_for_stmt (current_stmt); - GROUP_NEXT_ELEMENT (current_stmt_info) = loop_use_stmt; - GROUP_FIRST_ELEMENT (use_stmt_info) - = GROUP_FIRST_ELEMENT (current_stmt_info); - } - else - GROUP_FIRST_ELEMENT (use_stmt_info) = loop_use_stmt; + reduc_chain.safe_push (use_stmt_info); lhs = gimple_assign_lhs (loop_use_stmt); - current_stmt = loop_use_stmt; size++; } @@ -2889,9 +2889,9 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi, /* Swap the operands, if needed, to make the reduction operand be the second operand. */ lhs = PHI_RESULT (phi); - next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); - while (next_stmt) + for (unsigned i = 0; i < reduc_chain.length (); ++i) { + gassign *next_stmt = as_a (reduc_chain[i]->stmt); if (gimple_assign_rhs2 (next_stmt) == lhs) { tree op = gimple_assign_rhs1 (next_stmt); @@ -2916,7 +2916,6 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi, && !is_loop_header_bb_p (gimple_bb (def_stmt))))) { lhs = gimple_assign_lhs (next_stmt); - next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); continue; } @@ -2964,13 +2963,20 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi, } lhs = gimple_assign_lhs (next_stmt); - next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); } + /* Build up the actual chain. */ + for (unsigned i = 0; i < reduc_chain.length () - 1; ++i) + { + GROUP_FIRST_ELEMENT (reduc_chain[i]) = reduc_chain[0]->stmt; + GROUP_NEXT_ELEMENT (reduc_chain[i]) = reduc_chain[i+1]->stmt; + } + GROUP_FIRST_ELEMENT (reduc_chain.last ()) = reduc_chain[0]->stmt; + GROUP_NEXT_ELEMENT (reduc_chain.last ()) = NULL; + /* Save the chain for further analysis in SLP detection. */ - first = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); - LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (first); - GROUP_SIZE (vinfo_for_stmt (first)) = size; + LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (reduc_chain[0]->stmt); + GROUP_SIZE (reduc_chain[0]) = size; return true; } @@ -5558,6 +5564,9 @@ vect_create_epilog_for_reduction (vec vect_defs, gimple *stmt, if (STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info) == INTEGER_INDUC_COND_REDUCTION) code = induc_code; + else if (STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info) + == CONST_COND_REDUCTION) + code = STMT_VINFO_VEC_CONST_COND_REDUC_CODE (stmt_info); else code = MAX_EXPR; } @@ -6312,7 +6321,7 @@ vectorize_fold_left_reduction (gimple *stmt, gimple_stmt_iterator *gsi, /* Remove the statement, so that we can use the same code paths as for statements that we've just created. */ gimple_stmt_iterator tmp_gsi = gsi_for_stmt (new_stmt); - gsi_remove (&tmp_gsi, false); + gsi_remove (&tmp_gsi, true); } if (i == vec_num - 1) diff --git a/contrib/gcc-8.0/gcc/tree-vect-slp.c b/contrib/gcc-8.0/gcc/tree-vect-slp.c index 73aa2271b5..625e99a787 100644 --- a/contrib/gcc-8.0/gcc/tree-vect-slp.c +++ b/contrib/gcc-8.0/gcc/tree-vect-slp.c @@ -2819,21 +2819,48 @@ vect_slp_analyze_node_operations (vec_info *vinfo, slp_tree node, = vect_get_num_vectors (vf * group_size, vectype); } + /* ??? We have to catch the case late where two first scalar stmts appear + in multiple SLP children with different def type and fail. Remember + original def types first since SLP_TREE_DEF_TYPE doesn't necessarily + match it when that is vect_internal_def. */ + auto_vec dt; + dt.safe_grow (SLP_TREE_CHILDREN (node).length ()); + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) + dt[j] + = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0])); + /* Push SLP node def-type to stmt operands. */ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) if (SLP_TREE_DEF_TYPE (child) != vect_internal_def) STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0])) = SLP_TREE_DEF_TYPE (child); - bool res = vect_analyze_stmt (stmt, &dummy, node, node_instance); + + /* Check everything worked out. */ + bool res = true; + FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) + if (SLP_TREE_DEF_TYPE (child) != vect_internal_def) + { + if (STMT_VINFO_DEF_TYPE + (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0])) + != SLP_TREE_DEF_TYPE (child)) + res = false; + } + else if (STMT_VINFO_DEF_TYPE + (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0])) != dt[j]) + res = false; + if (!res && dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: same operand with different " + "def type in stmt.\n"); + if (res) + res = vect_analyze_stmt (stmt, &dummy, node, node_instance); + /* Restore def-types. */ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) - if (SLP_TREE_DEF_TYPE (child) != vect_internal_def) - STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0])) - = vect_internal_def; - if (! res) - return false; + STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0])) + = dt[j]; - return true; + return res; } @@ -4064,15 +4091,15 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance, /* See if we have already vectorized the same set of stmts and reuse their vectorized stmts. */ - slp_tree &leader - = bst_map->get_or_insert (SLP_TREE_SCALAR_STMTS (node).copy ()); - if (leader) + if (slp_tree *leader = bst_map->get (SLP_TREE_SCALAR_STMTS (node))) { - SLP_TREE_VEC_STMTS (node).safe_splice (SLP_TREE_VEC_STMTS (leader)); + SLP_TREE_VEC_STMTS (node).safe_splice (SLP_TREE_VEC_STMTS (*leader)); + SLP_TREE_NUMBER_OF_VEC_STMTS (node) + = SLP_TREE_NUMBER_OF_VEC_STMTS (*leader); return false; } - leader = node; + bst_map->put (SLP_TREE_SCALAR_STMTS (node).copy (), node); FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child) vect_schedule_slp_instance (child, instance, bst_map); diff --git a/contrib/gcc-8.0/gcc/tree-vect-stmts.c b/contrib/gcc-8.0/gcc/tree-vect-stmts.c index 3e73118d99..c3c16416e2 100644 --- a/contrib/gcc-8.0/gcc/tree-vect-stmts.c +++ b/contrib/gcc-8.0/gcc/tree-vect-stmts.c @@ -1637,7 +1637,7 @@ vect_finish_replace_stmt (gimple *stmt, gimple *vec_stmt) gcc_assert (gimple_get_lhs (stmt) == gimple_get_lhs (vec_stmt)); gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - gsi_replace (&gsi, vec_stmt, false); + gsi_replace (&gsi, vec_stmt, true); vect_finish_stmt_generation_1 (stmt, vec_stmt); } @@ -3745,7 +3745,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not considering SIMD clones; not yet supported" " for variable-width vectors.\n"); - return NULL; + return false; } unsigned int badness = 0; @@ -5381,6 +5381,15 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi, FOR_EACH_VEC_ELT (stmts, k, slpstmt) if (!operand_equal_p (gimple_assign_rhs2 (slpstmt), op1, 0)) scalar_shift_arg = false; + + /* For internal SLP defs we have to make sure we see scalar stmts + for all vector elements. + ??? For different vectors we could resort to a different + scalar shift operand but code-generation below simply always + takes the first. */ + if (dt[1] == vect_internal_def + && maybe_ne (nunits_out * SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node), stmts.length ())) + scalar_shift_arg = false; } /* If the shift amount is computed by a pattern stmt we cannot @@ -5923,15 +5932,34 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi, /* Handle uses. */ if (j == 0) { - if (op_type == binary_op || op_type == ternary_op) + if (op_type == binary_op) vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, slp_node); + else if (op_type == ternary_op) + { + if (slp_node) + { + auto_vec ops(3); + ops.quick_push (op0); + ops.quick_push (op1); + ops.quick_push (op2); + auto_vec > vec_defs(3); + vect_get_slp_defs (ops, slp_node, &vec_defs); + vec_oprnds0 = vec_defs[0]; + vec_oprnds1 = vec_defs[1]; + vec_oprnds2 = vec_defs[2]; + } + else + { + vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, + NULL); + vect_get_vec_defs (op2, NULL_TREE, stmt, &vec_oprnds2, NULL, + NULL); + } + } else vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL, slp_node); - if (op_type == ternary_op) - vect_get_vec_defs (op2, NULL_TREE, stmt, &vec_oprnds2, NULL, - slp_node); } else { @@ -7634,6 +7662,10 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, } ltype = build_aligned_type (ltype, TYPE_ALIGN (TREE_TYPE (vectype))); } + /* Load vector(1) scalar_type if it's 1 element-wise vectype. */ + else if (nloads == 1) + ltype = vectype; + if (slp) { /* For SLP permutation support we need to load the whole group, @@ -8487,7 +8519,7 @@ vect_is_simple_cond (tree cond, vec_info *vinfo, *comp_vectype = vectype1 ? vectype1 : vectype2; /* Invariant comparison. */ - if (! *comp_vectype) + if (! *comp_vectype && vectype) { tree scalar_type = TREE_TYPE (lhs); /* If we can widen the comparison to match vectype do so. */ @@ -8599,7 +8631,7 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi, else_clause = gimple_assign_rhs3 (stmt); if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo, - &comp_vectype, &dts[0], vectype) + &comp_vectype, &dts[0], slp_node ? NULL : vectype) || !comp_vectype) return false; @@ -9579,7 +9611,7 @@ vect_transform_stmt (gimple *stmt, gimple_stmt_iterator *gsi, if (gimple_code (stmt) == GIMPLE_PHI) scalar_dest = PHI_RESULT (stmt); else - scalar_dest = gimple_assign_lhs (stmt); + scalar_dest = gimple_get_lhs (stmt); FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest) { diff --git a/contrib/gcc-8.0/gcc/tree-vectorizer.h b/contrib/gcc-8.0/gcc/tree-vectorizer.h index 7e2b00f343..3cf1dfa688 100644 --- a/contrib/gcc-8.0/gcc/tree-vectorizer.h +++ b/contrib/gcc-8.0/gcc/tree-vectorizer.h @@ -1047,32 +1047,22 @@ set_vinfo_for_stmt (gimple *stmt, stmt_vec_info info) } } -/* Return the earlier statement between STMT1 and STMT2. */ +/* Return TRUE if a statement represented by STMT_INFO is a part of a + pattern. */ -static inline gimple * -get_earlier_stmt (gimple *stmt1, gimple *stmt2) +static inline bool +is_pattern_stmt_p (stmt_vec_info stmt_info) { - unsigned int uid1, uid2; - - if (stmt1 == NULL) - return stmt2; - - if (stmt2 == NULL) - return stmt1; - - uid1 = gimple_uid (stmt1); - uid2 = gimple_uid (stmt2); - - if (uid1 == 0 || uid2 == 0) - return NULL; + gimple *related_stmt; + stmt_vec_info related_stmt_info; - gcc_checking_assert (uid1 <= stmt_vec_info_vec.length () - && uid2 <= stmt_vec_info_vec.length ()); + related_stmt = STMT_VINFO_RELATED_STMT (stmt_info); + if (related_stmt + && (related_stmt_info = vinfo_for_stmt (related_stmt)) + && STMT_VINFO_IN_PATTERN_P (related_stmt_info)) + return true; - if (uid1 < uid2) - return stmt1; - else - return stmt2; + return false; } /* Return the later statement between STMT1 and STMT2. */ @@ -1088,8 +1078,12 @@ get_later_stmt (gimple *stmt1, gimple *stmt2) if (stmt2 == NULL) return stmt1; - uid1 = gimple_uid (stmt1); - uid2 = gimple_uid (stmt2); + stmt_vec_info stmt_info1 = vinfo_for_stmt (stmt1); + stmt_vec_info stmt_info2 = vinfo_for_stmt (stmt2); + uid1 = gimple_uid (is_pattern_stmt_p (stmt_info1) + ? STMT_VINFO_RELATED_STMT (stmt_info1) : stmt1); + uid2 = gimple_uid (is_pattern_stmt_p (stmt_info2) + ? STMT_VINFO_RELATED_STMT (stmt_info2) : stmt2); if (uid1 == 0 || uid2 == 0) return NULL; @@ -1103,24 +1097,6 @@ get_later_stmt (gimple *stmt1, gimple *stmt2) return stmt2; } -/* Return TRUE if a statement represented by STMT_INFO is a part of a - pattern. */ - -static inline bool -is_pattern_stmt_p (stmt_vec_info stmt_info) -{ - gimple *related_stmt; - stmt_vec_info related_stmt_info; - - related_stmt = STMT_VINFO_RELATED_STMT (stmt_info); - if (related_stmt - && (related_stmt_info = vinfo_for_stmt (related_stmt)) - && STMT_VINFO_IN_PATTERN_P (related_stmt_info)) - return true; - - return false; -} - /* Return true if BB is a loop header. */ static inline bool diff --git a/contrib/gcc-8.0/gcc/tree-vrp.c b/contrib/gcc-8.0/gcc/tree-vrp.c index aa53db6557..8f897cfdd4 100644 --- a/contrib/gcc-8.0/gcc/tree-vrp.c +++ b/contrib/gcc-8.0/gcc/tree-vrp.c @@ -3844,10 +3844,10 @@ register_edge_assert_for_1 (tree op, enum tree_code code, Such comparison can yield assertions like X >= XX...X00...0 X <= XX...X11...1 - in case of COND_OP being NE_EXPR or + in case of COND_OP being EQ_EXPR or X < XX...X00...0 X > XX...X11...1 - in case of EQ_EXPR. */ + in case of NE_EXPR. */ static bool is_masked_range_test (tree name, tree valt, enum tree_code cond_code, @@ -3867,6 +3867,10 @@ is_masked_range_test (tree name, tree valt, enum tree_code cond_code, wi::tree_to_wide_ref mask = wi::to_wide (maskt); wide_int inv_mask = ~mask; + /* Must have been removed by now so don't bother optimizing. */ + if (mask == 0 || inv_mask == 0) + return false; + /* Assume VALT is INTEGER_CST. */ wi::tree_to_wide_ref val = wi::to_wide (valt); @@ -3907,9 +3911,6 @@ is_masked_range_test (tree name, tree valt, enum tree_code cond_code, *low = wide_int_to_tree (type, val); *high = wide_int_to_tree (type, val | inv_mask); - if (wi::neg_p (val, TYPE_SIGN (type))) - std::swap (*low, *high); - return true; } @@ -5921,9 +5922,9 @@ union_ranges (enum value_range_type *vr0type, if (TREE_CODE (*vr0min) == INTEGER_CST) { *vr0type = vr1type; - *vr0min = vr1min; *vr0max = int_const_binop (MINUS_EXPR, *vr0min, build_int_cst (TREE_TYPE (*vr0min), 1)); + *vr0min = vr1min; } else goto give_up; diff --git a/contrib/gcc-8.0/gcc/tree.c b/contrib/gcc-8.0/gcc/tree.c index e93f24dd4d..091a63a1a8 100644 --- a/contrib/gcc-8.0/gcc/tree.c +++ b/contrib/gcc-8.0/gcc/tree.c @@ -5824,7 +5824,12 @@ free_lang_data (void) /* If we are the LTO frontend we have freed lang-specific data already. */ if (in_lto_p || (!flag_generate_lto && !flag_generate_offload)) - return 0; + { + /* Rebuild type inheritance graph even when not doing LTO to get + consistent profile data. */ + rebuild_type_inheritance_graph (); + return 0; + } /* Provide a dummy TRANSLATION_UNIT_DECL if the FE failed to provide one. */ if (vec_safe_is_empty (all_translation_units)) @@ -6616,7 +6621,8 @@ type_hash_canon (unsigned int hashcode, tree type) if (*loc) { tree t1 = ((type_hash *) *loc)->type; - gcc_assert (TYPE_MAIN_VARIANT (t1) == t1); + gcc_assert (TYPE_MAIN_VARIANT (t1) == t1 + && t1 != type); if (TYPE_UID (type) + 1 == next_type_uid) --next_type_uid; /* Free also min/max values and the cache for integer @@ -7351,6 +7357,9 @@ add_expr (const_tree t, inchash::hash &hstate, unsigned int flags) for (i = 0; i < TREE_VEC_LENGTH (t); ++i) inchash::add_expr (TREE_VEC_ELT (t, i), hstate, flags); return; + case IDENTIFIER_NODE: + hstate.add_object (IDENTIFIER_HASH_VALUE (t)); + return; case FUNCTION_DECL: /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form. Otherwise nodes that compare equal according to operand_equal_p might @@ -8014,6 +8023,8 @@ build_function_type (tree value_type, tree arg_types) bool any_structural_p, any_noncanonical_p; tree canon_argtypes; + gcc_assert (arg_types != error_mark_node); + if (TREE_CODE (value_type) == FUNCTION_TYPE) { error ("function return type cannot be function"); @@ -9780,8 +9791,7 @@ build_common_tree_nodes (bool signed_char) TYPE_SIZE (int_n_trees[i].signed_type) = bitsize_int (int_n_data[i].bitsize); TYPE_SIZE (int_n_trees[i].unsigned_type) = bitsize_int (int_n_data[i].bitsize); - if (int_n_data[i].bitsize > LONG_LONG_TYPE_SIZE - && int_n_enabled_p[i]) + if (int_n_enabled_p[i]) { integer_types[itk_intN_0 + i * 2] = int_n_trees[i].signed_type; integer_types[itk_unsigned_intN_0 + i * 2] = int_n_trees[i].unsigned_type; diff --git a/contrib/gcc-8.0/gcc/tree.h b/contrib/gcc-8.0/gcc/tree.h index 1e14d9f586..324ef5b45e 100644 --- a/contrib/gcc-8.0/gcc/tree.h +++ b/contrib/gcc-8.0/gcc/tree.h @@ -1263,6 +1263,9 @@ extern tree maybe_wrap_with_location (tree, location_t); ASM_OPERAND with no operands. */ #define ASM_INPUT_P(NODE) (ASM_EXPR_CHECK (NODE)->base.static_flag) #define ASM_VOLATILE_P(NODE) (ASM_EXPR_CHECK (NODE)->base.public_flag) +/* Nonzero if we want to consider this asm as minimum length and cost + for inlining decisions. */ +#define ASM_INLINE_P(NODE) (ASM_EXPR_CHECK (NODE)->base.protected_flag) /* COND_EXPR accessors. */ #define COND_EXPR_COND(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 0)) @@ -3061,6 +3064,10 @@ extern vec **decl_debug_args_insert (tree); #define DECL_CXX_DESTRUCTOR_P(NODE)\ (FUNCTION_DECL_CHECK (NODE)->decl_with_vis.cxx_destructor) +/* In FUNCTION_DECL, this is set if this function is a lambda function. */ +#define DECL_LAMBDA_FUNCTION(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.lambda_function) + /* In FUNCTION_DECL that represent an virtual method this is set when the method is final. */ #define DECL_FINAL_P(NODE)\ diff --git a/contrib/gcc-8.0/gcc/valtrack.c b/contrib/gcc-8.0/gcc/valtrack.c index 4741d00107..5c36db16c1 100644 --- a/contrib/gcc-8.0/gcc/valtrack.c +++ b/contrib/gcc-8.0/gcc/valtrack.c @@ -56,8 +56,6 @@ static rtx cleanup_auto_inc_dec (rtx src, machine_mode mem_mode ATTRIBUTE_UNUSED) { rtx x = src; - if (!AUTO_INC_DEC) - return copy_rtx (x); const RTX_CODE code = GET_CODE (x); int i; diff --git a/contrib/gcc-8.0/gcc/value-prof.c b/contrib/gcc-8.0/gcc/value-prof.c index 16cdbd64f4..d845faf556 100644 --- a/contrib/gcc-8.0/gcc/value-prof.c +++ b/contrib/gcc-8.0/gcc/value-prof.c @@ -1202,7 +1202,7 @@ init_node_map (bool local) cgraph_node_map = new hash_map; FOR_EACH_DEFINED_FUNCTION (n) - if (n->has_gimple_body_p ()) + if (n->has_gimple_body_p () || n->thunk.thunk_p) { cgraph_node **val; if (local) diff --git a/contrib/gcc-8.0/gcc/value-prof.h b/contrib/gcc-8.0/gcc/value-prof.h index d0b8cda181..55b1dd1841 100644 --- a/contrib/gcc-8.0/gcc/value-prof.h +++ b/contrib/gcc-8.0/gcc/value-prof.h @@ -112,7 +112,8 @@ extern struct cgraph_node* find_func_by_profile_id (int func_id); /* In profile.c. */ extern void init_branch_prob (void); -extern void branch_prob (void); +extern void branch_prob (bool); +extern void read_thunk_profile (struct cgraph_node *); extern void end_branch_prob (void); #endif /* GCC_VALUE_PROF_H */ diff --git a/contrib/gcc-8.0/gcc/var-tracking.c b/contrib/gcc-8.0/gcc/var-tracking.c index 2b21da3dfc..80014e437d 100644 --- a/contrib/gcc-8.0/gcc/var-tracking.c +++ b/contrib/gcc-8.0/gcc/var-tracking.c @@ -964,6 +964,24 @@ use_narrower_mode_test (rtx x, const_rtx subreg) case MULT: break; case ASHIFT: + if (GET_MODE (XEXP (x, 1)) != VOIDmode) + { + enum machine_mode mode = GET_MODE (subreg); + rtx op1 = XEXP (x, 1); + enum machine_mode op1_mode = GET_MODE (op1); + if (GET_MODE_PRECISION (as_a (mode)) + < GET_MODE_PRECISION (as_a (op1_mode))) + { + poly_uint64 byte = subreg_lowpart_offset (mode, op1_mode); + if (GET_CODE (op1) == SUBREG || GET_CODE (op1) == CONCAT) + { + if (!simplify_subreg (mode, op1, op1_mode, byte)) + return false; + } + else if (!validate_subreg (mode, op1_mode, op1, byte)) + return false; + } + } iter.substitute (XEXP (x, 0)); break; default: diff --git a/contrib/gcc-8.0/gcc/varasm.c b/contrib/gcc-8.0/gcc/varasm.c index d24bac4ad8..2a1eac0f99 100644 --- a/contrib/gcc-8.0/gcc/varasm.c +++ b/contrib/gcc-8.0/gcc/varasm.c @@ -296,6 +296,17 @@ get_section (const char *name, unsigned int flags, tree decl) else { sect = *slot; + /* It is fine if one of the sections has SECTION_NOTYPE as long as + the other has none of the contrary flags (see the logic at the end + of default_section_type_flags, below). */ + if (((sect->common.flags ^ flags) & SECTION_NOTYPE) + && !((sect->common.flags | flags) + & (SECTION_CODE | SECTION_BSS | SECTION_TLS | SECTION_ENTSIZE + | (HAVE_COMDAT_GROUP ? SECTION_LINKONCE : 0)))) + { + sect->common.flags |= SECTION_NOTYPE; + flags |= SECTION_NOTYPE; + } if ((sect->common.flags & ~SECTION_DECLARED) != flags && ((sect->common.flags | flags) & SECTION_OVERRIDE) == 0) { @@ -2943,6 +2954,11 @@ decode_addr_const (tree exp, struct addr_const *value) gen_rtx_SYMBOL_REF (Pmode, "origin of addresses")); break; + case COMPOUND_LITERAL_EXPR: + gcc_assert (COMPOUND_LITERAL_EXPR_DECL (target)); + x = DECL_RTL (COMPOUND_LITERAL_EXPR_DECL (target)); + break; + default: gcc_unreachable (); } @@ -5821,7 +5837,8 @@ do_assemble_alias (tree decl, tree target) globalize_decl (decl); maybe_assemble_visibility (decl); } - if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + if (TREE_CODE (decl) == FUNCTION_DECL + && cgraph_node::get (decl)->ifunc_resolver) { #if defined (ASM_OUTPUT_TYPE_DIRECTIVE) if (targetm.has_ifunc_p ()) @@ -5904,7 +5921,9 @@ assemble_alias (tree decl, tree target) # else if (!DECL_WEAK (decl)) { - if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + /* NB: ifunc_resolver isn't set when an error is detected. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) error_at (DECL_SOURCE_LOCATION (decl), "ifunc is not supported in this configuration"); else @@ -6360,15 +6379,23 @@ default_section_type_flags (tree decl, const char *name, int reloc) || strncmp (name, ".gnu.linkonce.tb.", 17) == 0) flags |= SECTION_TLS | SECTION_BSS; - /* These three sections have special ELF types. They are neither - SHT_PROGBITS nor SHT_NOBITS, so when changing sections we don't - want to print a section type (@progbits or @nobits). If someone - is silly enough to emit code or TLS variables to one of these - sections, then don't handle them specially. */ - if (!(flags & (SECTION_CODE | SECTION_BSS | SECTION_TLS)) - && (strcmp (name, ".init_array") == 0 - || strcmp (name, ".fini_array") == 0 - || strcmp (name, ".preinit_array") == 0)) + /* Various sections have special ELF types that the assembler will + assign by default based on the name. They are neither SHT_PROGBITS + nor SHT_NOBITS, so when changing sections we don't want to print a + section type (@progbits or @nobits). Rather than duplicating the + assembler's knowledge of what those special name patterns are, just + let the assembler choose the type if we don't know a specific + reason to set it to something other than the default. SHT_PROGBITS + is the default for sections whose name is not specially known to + the assembler, so it does no harm to leave the choice to the + assembler when @progbits is the best thing we know to use. If + someone is silly enough to emit code or TLS variables to one of + these sections, then don't handle them specially. + + default_elf_asm_named_section (below) handles the BSS, TLS, ENTSIZE, and + LINKONCE cases when NOTYPE is not set, so leave those to its logic. */ + if (!(flags & (SECTION_CODE | SECTION_BSS | SECTION_TLS | SECTION_ENTSIZE)) + && !(HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))) flags |= SECTION_NOTYPE; return flags; @@ -6454,6 +6481,10 @@ default_elf_asm_named_section (const char *name, unsigned int flags, fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars); + /* default_section_type_flags (above) knows which flags need special + handling here, and sets NOTYPE when none of these apply so that the + assembler's logic for default types can apply to user-chosen + section names. */ if (!(flags & SECTION_NOTYPE)) { const char *type; @@ -7024,7 +7055,8 @@ default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, weakref alias. */ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)) || (TREE_CODE (exp) == FUNCTION_DECL - && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp)))) + && cgraph_node::get (exp) + && cgraph_node::get (exp)->ifunc_resolver)) return false; /* Static variables are always local. */ diff --git a/contrib/gcc-8.0/gcc/varpool.c b/contrib/gcc-8.0/gcc/varpool.c index 418753cca2..6c91acbec6 100644 --- a/contrib/gcc-8.0/gcc/varpool.c +++ b/contrib/gcc-8.0/gcc/varpool.c @@ -333,16 +333,16 @@ varpool_node::ctor_useable_for_folding_p (void) if (TREE_THIS_VOLATILE (decl)) return false; + /* Avoid attempts to load constructors that was not streamed. */ + if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node + && real_node->body_removed) + return false; + /* If we do not have a constructor, we can't use it. */ if (DECL_INITIAL (real_node->decl) == error_mark_node && !real_node->lto_file_data) return false; - /* Avoid attempts to load constructors that was not streamed. */ - if (flag_ltrans && DECL_INITIAL (real_node->decl) == error_mark_node - && real_node->body_removed) - return false; - /* Vtables are defined by their types and must match no matter of interposition rules. */ if (DECL_VIRTUAL_P (decl)) diff --git a/contrib/gcc-8.0/gcc/vr-values.c b/contrib/gcc-8.0/gcc/vr-values.c index b1f587d2b9..22243e95bd 100644 --- a/contrib/gcc-8.0/gcc/vr-values.c +++ b/contrib/gcc-8.0/gcc/vr-values.c @@ -2901,7 +2901,9 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) if (cmp_min < 0) vr_result->min = lhs_vr->min; else if (cmp_min > 0 - && !vrp_val_is_min (vr_result->min)) + && (TREE_CODE (vr_result->min) != INTEGER_CST + || tree_int_cst_lt (vrp_val_min (TREE_TYPE (vr_result->min)), + vr_result->min))) vr_result->min = int_const_binop (PLUS_EXPR, vrp_val_min (TREE_TYPE (vr_result->min)), @@ -2911,7 +2913,9 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) if (cmp_max > 0) vr_result->max = lhs_vr->max; else if (cmp_max < 0 - && !vrp_val_is_max (vr_result->max)) + && (TREE_CODE (vr_result->max) != INTEGER_CST + || tree_int_cst_lt (vr_result->max, + vrp_val_max (TREE_TYPE (vr_result->min))))) vr_result->max = int_const_binop (MINUS_EXPR, vrp_val_max (TREE_TYPE (vr_result->min)), diff --git a/contrib/gcc-8.0/libbacktrace/elf.c b/contrib/gcc-8.0/libbacktrace/elf.c index 0fd5e6f9d0..f4863f0bea 100644 --- a/contrib/gcc-8.0/libbacktrace/elf.c +++ b/contrib/gcc-8.0/libbacktrace/elf.c @@ -2868,7 +2868,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, if (note->type == NT_GNU_BUILD_ID && note->namesz == 4 && strncmp (note->name, "GNU", 4) == 0 - && shdr->sh_size < 12 + ((note->namesz + 3) & ~ 3) + note->descsz) + && shdr->sh_size <= 12 + ((note->namesz + 3) & ~ 3) + note->descsz) { buildid_data = ¬e->name[0] + ((note->namesz + 3) & ~ 3); buildid_size = note->descsz; diff --git a/contrib/gcc-8.0/libgcc/config/i386/cpuinfo.c b/contrib/gcc-8.0/libgcc/config/i386/cpuinfo.c index 86953db274..d1853d5515 100644 --- a/contrib/gcc-8.0/libgcc/config/i386/cpuinfo.c +++ b/contrib/gcc-8.0/libgcc/config/i386/cpuinfo.c @@ -83,17 +83,20 @@ get_amd_cpu (unsigned int family, unsigned int model) /* AMD Family 15h "Bulldozer". */ case 0x15: __cpu_model.__cpu_type = AMDFAM15H; + + if (model == 0x2) + __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2; /* Bulldozer version 1. */ - if ( model <= 0xf) + else if (model <= 0xf) __cpu_model.__cpu_subtype = AMDFAM15H_BDVER1; /* Bulldozer version 2 "Piledriver" */ - if (model >= 0x10 && model <= 0x2f) + else if (model <= 0x2f) __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2; /* Bulldozer version 3 "Steamroller" */ - if (model >= 0x30 && model <= 0x4f) + else if (model <= 0x4f) __cpu_model.__cpu_subtype = AMDFAM15H_BDVER3; /* Bulldozer version 4 "Excavator" */ - if (model >= 0x60 && model <= 0x7f) + else if (model <= 0x7f) __cpu_model.__cpu_subtype = AMDFAM15H_BDVER4; break; /* AMD Family 16h "btver2" */ diff --git a/contrib/gcc-8.0/libgcc/unwind-dw2.c b/contrib/gcc-8.0/libgcc/unwind-dw2.c index de9310f524..952288ed5c 100644 --- a/contrib/gcc-8.0/libgcc/unwind-dw2.c +++ b/contrib/gcc-8.0/libgcc/unwind-dw2.c @@ -225,7 +225,7 @@ _Unwind_GetGR (struct _Unwind_Context *context, int regno) _Unwind_Context_Reg_Val val; #ifdef DWARF_ZERO_REG - if (index == DWARF_ZERO_REG) + if (regno == DWARF_ZERO_REG) return 0; #endif diff --git a/contrib/gcc-8.0/libiberty/simple-object-elf.c b/contrib/gcc-8.0/libiberty/simple-object-elf.c index 7468a1adc3..021ce488c1 100644 --- a/contrib/gcc-8.0/libiberty/simple-object-elf.c +++ b/contrib/gcc-8.0/libiberty/simple-object-elf.c @@ -22,6 +22,10 @@ Boston, MA 02110-1301, USA. */ #include "simple-object.h" #include +/* mingw.org's MinGW doesn't have ENOTSUP. */ +#ifndef ENOTSUP +# define ENOTSUP ENOSYS +#endif #include #ifdef HAVE_STDLIB_H diff --git a/contrib/gcc-8.0/libiberty/simple-object.c b/contrib/gcc-8.0/libiberty/simple-object.c index 42aa6ac4e6..d2465c6e13 100644 --- a/contrib/gcc-8.0/libiberty/simple-object.c +++ b/contrib/gcc-8.0/libiberty/simple-object.c @@ -44,6 +44,10 @@ Boston, MA 02110-1301, USA. */ #define SEEK_SET 0 #endif +#ifndef O_BINARY +#define O_BINARY 0 +#endif + #include "simple-object-common.h" /* The known object file formats. */ @@ -326,7 +330,7 @@ simple_object_copy_lto_debug_sections (simple_object_read *sobj, return errmsg; } - outfd = creat (dest, 00777); + outfd = open (dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, 00777); if (outfd == -1) { *err = errno; diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/alloc_traits.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/alloc_traits.h index eee9d8502e..742fdd0447 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/alloc_traits.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/alloc_traits.h @@ -598,7 +598,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : is_copy_constructible<_Tp> { }; -#if __cplusplus >= 201103L // Trait to detect Allocator-like types. template struct __is_allocator : false_type { }; @@ -612,10 +611,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template using _RequireAllocator = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type; -#endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std - -#endif -#endif +#endif // C++11 +#endif // _ALLOC_TRAITS_H diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.h index 3e8310e762..0f5d398fcf 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.h @@ -506,6 +506,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @param __s Source C string. * @param __a Allocator to use (default is default allocator). */ +#if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3076. basic_string CTAD ambiguity + template> +#endif basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); } @@ -516,6 +521,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @param __c Character to use. * @param __a Allocator to use (default is default allocator). */ +#if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3076. basic_string CTAD ambiguity + template> +#endif basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { _M_construct(__n, __c); } @@ -734,20 +744,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 // 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())) + if (__str._M_is_local()) { + // We've always got room for a short string, just copy it. + if (__str.size()) + this->_S_copy(_M_data(), __str._M_data(), __str.size()); + _M_set_length(__str.size()); + } + else if (_Alloc_traits::_S_propagate_on_move_assign() + || _Alloc_traits::_S_always_equal() + || _M_get_allocator() == __str._M_get_allocator()) + { + // Just move the allocated pointer, our allocator can free it. pointer __data = nullptr; size_type __capacity; if (!_M_is_local()) { if (_Alloc_traits::_S_always_equal()) { + // __str can reuse our existing storage. __data = _M_data(); __capacity = _M_allocated_capacity; } - else + else // __str can't use it, so free it. _M_destroy(_M_allocated_capacity); } @@ -762,8 +781,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 else __str._M_data(__str._M_local_buf); } - else - assign(__str); + else // Need to do a deep copy + assign(__str); __str.clear(); return *this; } @@ -1216,7 +1235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * remainder of @a __str is appended. */ basic_string& - append(const basic_string& __str, size_type __pos, size_type __n) + append(const basic_string& __str, size_type __pos, size_type __n = npos) { return _M_append(__str._M_data() + __str._M_check(__pos, "basic_string::append"), __str._M_limit(__pos, __n)); } @@ -1381,7 +1400,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * __str, the remainder of @a __str is used. */ basic_string& - assign(const basic_string& __str, size_type __pos, size_type __n) + assign(const basic_string& __str, size_type __pos, size_type __n = npos) { return _M_replace(size_type(0), this->size(), __str._M_data() + __str._M_check(__pos, "basic_string::assign"), __str._M_limit(__pos, __n)); } @@ -1633,7 +1652,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ basic_string& insert(size_type __pos1, const basic_string& __str, - size_type __pos2, size_type __n) + size_type __pos2, size_type __n = npos) { return this->replace(__pos1, size_type(0), __str._M_data() + __str._M_check(__pos2, "basic_string::insert"), __str._M_limit(__pos2, __n)); } @@ -1881,7 +1900,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, - size_type __pos2, size_type __n2) + size_type __pos2, size_type __n2 = npos) { return this->replace(__pos1, __n1, __str._M_data() + __str._M_check(__pos2, "basic_string::replace"), __str._M_limit(__pos2, __n2)); } @@ -2941,7 +2960,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ int compare(size_type __pos1, size_type __n1, const basic_string& __str, - size_type __pos2, size_type __n2) const; + size_type __pos2, size_type __n2 = npos) const; /** * @brief Compare to a C string. @@ -4135,7 +4154,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 * remainder of @a __str is appended. */ basic_string& - append(const basic_string& __str, size_type __pos, size_type __n); + append(const basic_string& __str, size_type __pos, size_type __n = npos); /** * @brief Append a C substring. @@ -4280,7 +4299,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 * __str, the remainder of @a __str is used. */ basic_string& - assign(const basic_string& __str, size_type __pos, size_type __n) + assign(const basic_string& __str, size_type __pos, size_type __n = npos) { return this->assign(__str._M_data() + __str._M_check(__pos, "basic_string::assign"), __str._M_limit(__pos, __n)); } @@ -4468,7 +4487,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ basic_string& insert(size_type __pos1, const basic_string& __str, - size_type __pos2, size_type __n) + size_type __pos2, size_type __n = npos) { return this->insert(__pos1, __str._M_data() + __str._M_check(__pos2, "basic_string::insert"), __str._M_limit(__pos2, __n)); } @@ -4703,7 +4722,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, - size_type __pos2, size_type __n2) + size_type __pos2, size_type __n2 = npos) { return this->replace(__pos1, __n1, __str._M_data() + __str._M_check(__pos2, "basic_string::replace"), __str._M_limit(__pos2, __n2)); } @@ -5130,7 +5149,10 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ _CharT* data() noexcept - { return _M_data(); } + { + _M_leak(); + return _M_data(); + } #endif /** @@ -5779,7 +5801,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ int compare(size_type __pos1, size_type __n1, const basic_string& __str, - size_type __pos2, size_type __n2) const; + size_type __pos2, size_type __n2 = npos) const; /** * @brief Compare to a C string. @@ -5873,6 +5895,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 typename = _RequireAllocator<_Allocator>> basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3075. basic_string needs deduction guides from basic_string_view + template, + typename = _RequireAllocator<_Allocator>> + basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) + -> basic_string<_CharT, _Traits, _Allocator>; + + template, + typename = _RequireAllocator<_Allocator>> + basic_string(basic_string_view<_CharT, _Traits>, + typename basic_string<_CharT, _Traits, _Allocator>::size_type, + typename basic_string<_CharT, _Traits, _Allocator>::size_type, + const _Allocator& = _Allocator()) + -> basic_string<_CharT, _Traits, _Allocator>; _GLIBCXX_END_NAMESPACE_CXX11 #endif diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.tcc b/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.tcc index be8815c711..04b68ca020 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.tcc +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.tcc @@ -1597,8 +1597,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. -#if _GLIBCXX_EXTERN_TEMPLATE > 0 && __cplusplus <= 201402L +#if _GLIBCXX_EXTERN_TEMPLATE + // The explicit instantiations definitions in src/c++11/string-inst.cc + // are compiled as C++14, so the new C++17 members aren't instantiated. + // Until those definitions are compiled as C++17 suppress the declaration, + // so C++17 code will implicitly instantiate std::string and std::wstring + // as needed. +# if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0 extern template class basic_string; +# elif ! _GLIBCXX_USE_CXX11_ABI + // Still need to prevent implicit instantiation of the COW empty rep, + // to ensure the definition in libstdc++.so is unique (PR 86138). + extern template basic_string::size_type + basic_string::_Rep::_S_empty_rep_storage[]; +# endif + extern template basic_istream& operator>>(basic_istream&, string&); @@ -1613,7 +1626,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION getline(basic_istream&, string&); #ifdef _GLIBCXX_USE_WCHAR_T +# if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0 extern template class basic_string; +# elif ! _GLIBCXX_USE_CXX11_ABI + extern template basic_string::size_type + basic_string::_Rep::_S_empty_rep_storage[]; +# endif + extern template basic_istream& operator>>(basic_istream&, wstring&); @@ -1626,8 +1645,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION extern template basic_istream& getline(basic_istream&, wstring&); -#endif -#endif +#endif // _GLIBCXX_USE_WCHAR_T +#endif // _GLIBCXX_EXTERN_TEMPLATE _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/c++config b/contrib/gcc-8.0/libstdc++-v3/include/bits/c++config index 1eb4679f67..bfe268da82 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/c++config +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/c++config @@ -609,4 +609,9 @@ namespace std # endif #endif +/* Define if __float128 is supported on this host. */ +#if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) +#define _GLIBCXX_USE_FLOAT128 +#endif + // End of prewritten config; the settings discovered at configure time follow. diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/char_traits.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/char_traits.h index 51cd321b8a..1945494d7e 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/char_traits.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/char_traits.h @@ -143,8 +143,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } }; -#define __cpp_lib_constexpr_char_traits 201611 - template _GLIBCXX14_CONSTEXPR int char_traits<_CharT>:: @@ -185,6 +183,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION char_traits<_CharT>:: move(char_type* __s1, const char_type* __s2, std::size_t __n) { + if (__n == 0) + return __s1; return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))); } @@ -217,6 +217,8 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus > 201402 +#define __cpp_lib_constexpr_char_traits 201611 + /** * @brief Determine whether the characters of a NULL-terminated * string are known at compile time. diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/cpp_type_traits.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/cpp_type_traits.h index ed6de4696c..960d469f41 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/cpp_type_traits.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/cpp_type_traits.h @@ -391,6 +391,17 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3) typedef __true_type __type; }; +#if __cplusplus >= 201703L + enum class byte : unsigned char; + + template<> + struct __is_byte + { + enum { __value = 1 }; + typedef __true_type __type; + }; +#endif // C++17 + // // Move iterator type // diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.h index b40256bd10..065635a708 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.h @@ -289,7 +289,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER struct _Fwd_list_base { protected: - typedef __alloc_rebind<_Alloc, _Tp> _Tp_alloc_type; typedef __alloc_rebind<_Alloc, _Fwd_list_node<_Tp>> _Node_alloc_type; typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits; @@ -299,7 +298,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Fwd_list_node_base _M_head; _Fwd_list_impl() - noexcept( noexcept(_Node_alloc_type()) ) + noexcept(is_nothrow_default_constructible<_Node_alloc_type>::value) : _Node_alloc_type(), _M_head() { } @@ -363,11 +362,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Node* __node = this->_M_get_node(); __try { - _Tp_alloc_type __a(_M_get_Node_allocator()); - typedef allocator_traits<_Tp_alloc_type> _Alloc_traits; ::new ((void*)__node) _Node; - _Alloc_traits::construct(__a, __node->_M_valptr(), - std::forward<_Args>(__args)...); + _Node_alloc_traits::construct(_M_get_Node_allocator(), + __node->_M_valptr(), + std::forward<_Args>(__args)...); } __catch(...) { @@ -437,10 +435,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef _Fwd_list_base<_Tp, _Alloc> _Base; typedef _Fwd_list_node<_Tp> _Node; typedef _Fwd_list_node_base _Node_base; - typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; typedef typename _Base::_Node_alloc_type _Node_alloc_type; typedef typename _Base::_Node_alloc_traits _Node_alloc_traits; - typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits; + typedef allocator_traits<__alloc_rebind<_Alloc, _Tp>> _Alloc_traits; public: // types: diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.tcc b/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.tcc index 3e12cd531d..b41fbbb52f 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.tcc +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/forward_list.tcc @@ -65,8 +65,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _Node* __curr = static_cast<_Node*>(__pos->_M_next); __pos->_M_next = __curr->_M_next; - _Tp_alloc_type __a(_M_get_Node_allocator()); - allocator_traits<_Tp_alloc_type>::destroy(__a, __curr->_M_valptr()); + _Node_alloc_traits::destroy(_M_get_Node_allocator(), + __curr->_M_valptr()); __curr->~_Node(); _M_put_node(__curr); return __pos->_M_next; @@ -83,8 +83,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _Node* __temp = __curr; __curr = static_cast<_Node*>(__curr->_M_next); - _Tp_alloc_type __a(_M_get_Node_allocator()); - allocator_traits<_Tp_alloc_type>::destroy(__a, __temp->_M_valptr()); + _Node_alloc_traits::destroy(_M_get_Node_allocator(), + __temp->_M_valptr()); __temp->~_Node(); _M_put_node(__temp); } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_dir.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_dir.h index 6b332e171c..9ee1cb66b6 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_dir.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_dir.h @@ -138,8 +138,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 refresh(__ec); } - void refresh() { _M_type = symlink_status().type(); } - void refresh(error_code& __ec) { _M_type = symlink_status(__ec).type(); } + void + refresh() + { _M_type = symlink_status().type(); } + + void + refresh(error_code& __ec) noexcept + { _M_type = symlink_status(__ec).type(); } // observers const filesystem::path& path() const noexcept { return _M_path; } @@ -313,7 +318,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _M_file_type(error_code& __ec) const noexcept { if (_M_type != file_type::none && _M_type != file_type::symlink) - return _M_type; + { + __ec.clear(); + return _M_type; + } return status(__ec).type(); } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_path.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_path.h index 31c34d67c7..fb85d489fd 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_path.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/fs_path.h @@ -106,7 +106,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template using _Path = typename - std::enable_if<__and_<__not_>, + std::enable_if<__and_<__not_, path>>, + __not_>, __constructible_from<_Tp1, _Tp2>>::value, path>::type; @@ -265,20 +266,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template _Path<_Source>& operator/=(_Source const& __source) - { return append(__source); } + { return _M_append(path(__source)); } template _Path<_Source>& append(_Source const& __source) - { - return _M_append(_S_convert(_S_range_begin(__source), - _S_range_end(__source))); - } + { return _M_append(path(__source)); } template _Path<_InputIterator, _InputIterator>& append(_InputIterator __first, _InputIterator __last) - { return _M_append(_S_convert(__first, __last)); } + { return _M_append(path(__first, __last)); } // concatenation @@ -379,7 +377,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 bool has_filename() const; bool has_stem() const; bool has_extension() const; - bool is_absolute() const; + bool is_absolute() const { return has_root_directory(); } bool is_relative() const { return !is_absolute(); } // generation @@ -406,17 +404,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 enum class _Split { _Stem, _Extension }; - path& _M_append(string_type&& __str) + path& + _M_append(path __p) { + if (__p.is_absolute()) + operator=(std::move(__p)); #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - operator/=(path(std::move(__str))); -#else - if (!_M_pathname.empty() && !_S_is_dir_sep(_M_pathname.back()) - && (__str.empty() || !_S_is_dir_sep(__str.front()))) - _M_pathname += preferred_separator; - _M_pathname += __str; - _M_split_cmpts(); + else if (__p.has_root_name() && __p.root_name() != root_name()) + operator=(std::move(__p)); #endif + else + operator/=(const_cast(__p)); return *this; } @@ -500,7 +498,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 struct _Cmpt; using _List = _GLIBCXX_STD_C::vector<_Cmpt>; _List _M_cmpts; // empty unless _M_type == _Type::_Multi - _Type _M_type = _Type::_Multi; + _Type _M_type = _Type::_Filename; }; template<> @@ -552,7 +550,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 /// Append one path to another inline path operator/(const path& __lhs, const path& __rhs) - { return path(__lhs) /= __rhs; } + { + path __result(__lhs); + __result /= __rhs; + return __result; + } /// Write a path to a stream template @@ -1070,22 +1072,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 return ext.first && ext.second != string_type::npos; } - inline bool - path::is_absolute() const - { -#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - return has_root_name(); -#else - return has_root_directory(); -#endif - } - inline path::iterator path::begin() const { if (_M_type == _Type::_Multi) return iterator(this, _M_cmpts.begin()); - return iterator(this, false); + return iterator(this, empty()); } inline path::iterator diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/hashtable.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/hashtable.h index af16e2c03c..ba1d35dbec 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/hashtable.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/hashtable.h @@ -1222,6 +1222,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_assign(__ht, [&__roan](__node_type* __n) { return __roan(std::move_if_noexcept(__n->_M_v())); }); + + if (__former_buckets) + _M_deallocate_buckets(__former_buckets, __former_bucket_count); __ht.clear(); } __catch(...) diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_conv.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_conv.h index bc5669f252..72680b9403 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_conv.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_conv.h @@ -35,10 +35,10 @@ #else #include -#include "stringfwd.h" -#include "allocator.h" -#include "codecvt.h" -#include "unique_ptr.h" +#include +#include +#include +#include namespace std _GLIBCXX_VISIBILITY(default) { diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_facets.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_facets.h index 7bce42232b..d5384e1469 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_facets.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_facets.h @@ -900,7 +900,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (_M_widen_ok == 1) { - __builtin_memcpy(__to, __lo, __hi - __lo); + if (__builtin_expect(__hi != __lo, true)) + __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } if (!_M_widen_ok) @@ -965,7 +966,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__builtin_expect(_M_narrow_ok == 1, true)) { - __builtin_memcpy(__to, __lo, __hi - __lo); + if (__builtin_expect(__hi != __lo, true)) + __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } if (!_M_narrow_ok) @@ -1104,7 +1106,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __to) const { - __builtin_memcpy(__to, __lo, __hi - __lo); + if (__builtin_expect(__hi != __lo, true)) + __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } @@ -1157,7 +1160,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION do_narrow(const char_type* __lo, const char_type* __hi, char __dfault __attribute__((__unused__)), char* __to) const { - __builtin_memcpy(__to, __lo, __hi - __lo); + if (__builtin_expect(__hi != __lo, true)) + __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/node_handle.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/node_handle.h index c02aca024b..8bb4f3c0ab 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/node_handle.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/node_handle.h @@ -109,7 +109,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using std::swap; swap(_M_ptr, __nh._M_ptr); - if (_AllocTraits::propagate_on_container_swap + if (_AllocTraits::propagate_on_container_swap::value || !_M_alloc || !__nh._M_alloc) _M_alloc.swap(__nh._M_alloc); else diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/quoted_string.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/quoted_string.h index b6e707a8a6..f6134da5a4 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/quoted_string.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/quoted_string.h @@ -64,6 +64,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _CharT _M_escape; }; +#if __cplusplus >= 201703L + template + struct _Quoted_string, _CharT> + { + _Quoted_string(basic_string_view<_CharT, _Traits> __str, + _CharT __del, _CharT __esc) + : _M_string(__str), _M_delim{__del}, _M_escape{__esc} + { } + + _Quoted_string& + operator=(_Quoted_string&) = delete; + + basic_string_view<_CharT, _Traits> _M_string; + _CharT _M_delim; + _CharT _M_escape; + }; +#endif // C++17 + /** * @brief Inserter for quoted strings. * @@ -101,7 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { std::basic_ostringstream<_CharT, _Traits> __ostr; __ostr << __str._M_delim; - for (auto& __c : __str._M_string) + for (auto __c : __str._M_string) { if (__c == __str._M_delim || __c == __str._M_escape) __ostr << __str._M_escape; diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/random.tcc b/contrib/gcc-8.0/libstdc++-v3/include/bits/random.tcc index 6db900cc0c..f398150d41 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/random.tcc +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/random.tcc @@ -2408,7 +2408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __v = __v * __v * __v; __u = __aurng(); } - while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n + while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n && (std::log(__u) > (0.5 * __n * __n + __a1 * (1.0 - __v + std::log(__v))))); @@ -2429,7 +2429,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __v = __v * __v * __v; __u = __aurng(); } - while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n + while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n && (std::log(__u) > (0.5 * __n * __n + __a1 * (1.0 - __v + std::log(__v))))); diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex.h index 92cf96c7e7..12e830b2c6 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex.h @@ -776,6 +776,48 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _AutomatonPtr _M_automaton; }; +#if __cplusplus < 201703L + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::icase; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::nosubs; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::optimize; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::collate; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::ECMAScript; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::basic; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::extended; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::awk; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::grep; + + template + constexpr regex_constants::syntax_option_type + basic_regex<_Ch, _Tr>::egrep; +#endif // ! C++17 + #if __cpp_deduction_guides >= 201606 template basic_regex(_ForwardIterator, _ForwardIterator, diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_automaton.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_automaton.h index bf51df7909..962a8450af 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_automaton.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_automaton.h @@ -333,7 +333,7 @@ namespace __detail "Number of NFA states exceeds limit. Please use shorter regex " "string, or use smaller brace expression, or make " "_GLIBCXX_REGEX_STATE_LIMIT larger."); - return this->size()-1; + return this->size() - 1; } // Eliminate dummy node in this NFA to make it compact. diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_compiler.tcc b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_compiler.tcc index 3342f146c9..8af920e5fe 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_compiler.tcc @@ -295,7 +295,7 @@ namespace __detail } #define __INSERT_REGEX_MATCHER(__func, ...)\ - do\ + do {\ if (!(_M_flags & regex_constants::icase))\ if (!(_M_flags & regex_constants::collate))\ __func(__VA_ARGS__);\ @@ -306,7 +306,7 @@ namespace __detail __func(__VA_ARGS__);\ else\ __func(__VA_ARGS__);\ - while (false) + } while (false) template bool diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_executor.tcc b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_executor.tcc index b3238894f5..68f1213cb6 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_executor.tcc +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/regex_executor.tcc @@ -366,11 +366,11 @@ namespace __detail _BiIter __actual_end) { if (!_M_icase) - return std::__equal4(__expected_begin, __expected_end, + return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end, __actual_begin, __actual_end); typedef std::ctype<_CharT> __ctype_type; const auto& __fctyp = use_facet<__ctype_type>(_M_traits.getloc()); - return std::__equal4(__expected_begin, __expected_end, + return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end, __actual_begin, __actual_end, [this, &__fctyp](_CharT __lhs, _CharT __rhs) { diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr.h index 2a54145083..8df6b7c0e8 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr.h @@ -355,9 +355,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: // This constructor is non-standard, it is used by allocate_shared. template - shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, - _Args&&... __args) - : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...) + shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) + : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...) { } template @@ -703,7 +702,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) { - return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, + return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a}, std::forward<_Args>(__args)...); } @@ -718,7 +717,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline shared_ptr<_Tp> make_shared(_Args&&... __args) { - typedef typename std::remove_const<_Tp>::type _Tp_nc; + typedef typename std::remove_cv<_Tp>::type _Tp_nc; return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), std::forward<_Args>(__args)...); } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr_base.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr_base.h index b58273a79c..29fc45a214 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr_base.h @@ -49,9 +49,7 @@ #ifndef _SHARED_PTR_BASE_H #define _SHARED_PTR_BASE_H 1 -#if __cpp_rtti -# include -#endif +#include #include #include #include @@ -59,10 +57,6 @@ namespace std _GLIBCXX_VISIBILITY(default) { -#if !__cpp_rtti - class type_info; -#endif - _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GLIBCXX_USE_DEPRECATED @@ -506,22 +500,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Sp_make_shared_tag { -#if !__cpp_rtti private: - template - friend class __shared_ptr; template friend class _Sp_counted_ptr_inplace; static const type_info& - _S_ti() noexcept + _S_ti() noexcept _GLIBCXX_VISIBILITY(default) { - static constexpr _Sp_make_shared_tag __tag; + alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { }; return reinterpret_cast(__tag); } -#endif }; + template + struct _Sp_alloc_shared_tag + { + const _Alloc& _M_a; + }; + template class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> { @@ -567,20 +563,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION this->~_Sp_counted_ptr_inplace(); } - // Sneaky trick so __shared_ptr can get the managed pointer + private: + friend class __shared_count<_Lp>; // To be able to call _M_ptr(). + + // No longer used, but code compiled against old libstdc++ headers + // might still call it from __shared_ptr ctor to get the pointer out. virtual void* - _M_get_deleter(const std::type_info& __ti) noexcept + _M_get_deleter(const std::type_info& __ti) noexcept override { + // Check for the fake type_info first, so we don't try to access it + // as a real type_info object. + if (&__ti == &_Sp_make_shared_tag::_S_ti()) + return const_cast::type*>(_M_ptr()); #if __cpp_rtti - if (__ti == typeid(_Sp_make_shared_tag)) + // Callers compiled with old libstdc++ headers and RTTI enabled + // might pass this instead: + else if (__ti == typeid(_Sp_make_shared_tag)) + return const_cast::type*>(_M_ptr()); #else - if (&__ti == &_Sp_make_shared_tag::_S_ti()) + // Cannot detect a real type_info object. If the linker keeps a + // definition of this function compiled with -fno-rtti then callers + // that have RTTI enabled and pass a real type_info object will get + // a null pointer returned. #endif - return const_cast::type*>(_M_ptr()); return nullptr; } - private: _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); } _Impl _M_impl; @@ -596,6 +604,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<_Lock_policy _Lp> class __shared_count { + template + struct __not_alloc_shared_tag { using type = void; }; + + template + struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { }; + public: constexpr __shared_count() noexcept : _M_pi(0) { } @@ -625,12 +639,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : __shared_count(__p, __sp_array_delete{}, allocator()) { } - template + template::type> __shared_count(_Ptr __p, _Deleter __d) : __shared_count(__p, std::move(__d), allocator()) { } - template + template::type> __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) { typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; @@ -651,18 +667,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a, + __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a, _Args&&... __args) - : _M_pi(0) { typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; - typename _Sp_cp_type::__allocator_type __a2(__a); + typename _Sp_cp_type::__allocator_type __a2(__a._M_a); auto __guard = std::__allocate_guarded(__a2); _Sp_cp_type* __mem = __guard.get(); - ::new (__mem) _Sp_cp_type(std::move(__a), - std::forward<_Args>(__args)...); - _M_pi = __mem; + auto __pi = ::new (__mem) + _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...); __guard = nullptr; + _M_pi = __pi; + __p = __pi->_M_ptr(); } #if _GLIBCXX_USE_DEPRECATED @@ -1322,21 +1338,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION protected: // This constructor is non-standard, it is used by allocate_shared. template - __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, - _Args&&... __args) - : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, - std::forward<_Args>(__args)...) - { - // _M_ptr needs to point to the newly constructed object. - // This relies on _Sp_counted_ptr_inplace::_M_get_deleter. -#if __cpp_rtti - void* __p = _M_refcount._M_get_deleter(typeid(__tag)); -#else - void* __p = _M_refcount._M_get_deleter(_Sp_make_shared_tag::_S_ti()); -#endif - _M_ptr = static_cast<_Tp*>(__p); - _M_enable_shared_from_this_with(_M_ptr); - } + __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) + : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...) + { _M_enable_shared_from_this_with(_M_ptr); } template @@ -1831,7 +1835,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline __shared_ptr<_Tp, _Lp> __allocate_shared(const _Alloc& __a, _Args&&... __args) { - return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a, + return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a}, std::forward<_Args>(__args)...); } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_bvector.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_bvector.h index de723edf50..e612c725ec 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_bvector.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_bvector.h @@ -469,8 +469,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : public _Bit_alloc_type, public _Bvector_impl_data { public: - _Bvector_impl() - _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type()) ) + _Bvector_impl() _GLIBCXX_NOEXCEPT_IF( + is_nothrow_default_constructible<_Bit_alloc_type>::value) : _Bit_alloc_type() { } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_iterator.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_iterator.h index 750b0c0f30..0a301ee79b 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_iterator.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_iterator.h @@ -122,6 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 235 No specification of default ctor for reverse_iterator + // 1012. reverse_iterator default ctor should value initialize _GLIBCXX17_CONSTEXPR reverse_iterator() : current() { } @@ -176,9 +177,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * This requires that @c --current is dereferenceable. */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2188. Reverse iterator does not fully support targets that overload & _GLIBCXX17_CONSTEXPR pointer operator->() const - { return &(operator*()); } + { return std::__addressof(operator*()); } /** * @return @c *this diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_list.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_list.h index 59e056df60..bb1910ee41 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_list.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_list.h @@ -384,7 +384,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { __detail::_List_node_header _M_node; - _List_impl() _GLIBCXX_NOEXCEPT_IF( noexcept(_Node_alloc_type()) ) + _List_impl() _GLIBCXX_NOEXCEPT_IF( + is_nothrow_default_constructible<_Node_alloc_type>::value) : _Node_alloc_type() { } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_map.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_map.h index a4a026ed34..da7c56c337 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_map.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_map.h @@ -808,12 +808,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(value_type&& __x) { return _M_t._M_insert_unique(std::move(__x)); } - template::value>::type> - std::pair + template + __enable_if_t::value, + pair> insert(_Pair&& __x) - { return _M_t._M_insert_unique(std::forward<_Pair>(__x)); } + { return _M_t._M_emplace_unique(std::forward<_Pair>(__x)); } #endif // @} @@ -869,13 +868,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(const_iterator __position, value_type&& __x) { return _M_t._M_insert_unique_(__position, std::move(__x)); } - template::value>::type> - iterator + template + __enable_if_t::value, iterator> insert(const_iterator __position, _Pair&& __x) - { return _M_t._M_insert_unique_(__position, - std::forward<_Pair>(__x)); } + { + return _M_t._M_emplace_hint_unique(__position, + std::forward<_Pair>(__x)); + } #endif // @} diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_multimap.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_multimap.h index fc8f454723..efd355f25d 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_multimap.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_multimap.h @@ -544,12 +544,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(value_type&& __x) { return _M_t._M_insert_equal(std::move(__x)); } - template::value>::type> - iterator + template + __enable_if_t::value, iterator> insert(_Pair&& __x) - { return _M_t._M_insert_equal(std::forward<_Pair>(__x)); } + { return _M_t._M_emplace_equal(std::forward<_Pair>(__x)); } #endif // @} @@ -589,13 +587,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(const_iterator __position, value_type&& __x) { return _M_t._M_insert_equal_(__position, std::move(__x)); } - template::value>::type> - iterator + template + __enable_if_t::value, iterator> insert(const_iterator __position, _Pair&& __x) - { return _M_t._M_insert_equal_(__position, - std::forward<_Pair>(__x)); } + { + return _M_t._M_emplace_hint_equal(__position, + std::forward<_Pair>(__x)); + } #endif // @} diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_pair.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_pair.h index a2486ba824..48af2b02ef 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_pair.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_pair.h @@ -185,8 +185,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __nonesuch_no_braces : std::__nonesuch { explicit __nonesuch_no_braces(const __nonesuch&) = delete; }; +#endif // C++11 -#endif + template class __pair_base + { +#if __cplusplus >= 201103L + template friend struct pair; + __pair_base() = default; + ~__pair_base() = default; + __pair_base(const __pair_base&) = default; + __pair_base& operator=(const __pair_base&) = delete; +#endif // C++11 + }; /** * @brief Struct holding two objects of arbitrary type. @@ -196,6 +206,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template struct pair + : private __pair_base<_T1, _T2> { typedef _T1 first_type; /// @c first_type is the first bound type typedef _T2 second_type; /// @c second_type is the second bound type @@ -374,19 +385,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } - pair& - operator=(typename conditional< - __not_<__and_, - is_copy_assignable<_T2>>>::value, - const pair&, const __nonesuch_no_braces&>::type __p) = delete; - pair& operator=(typename conditional< __and_, is_move_assignable<_T2>>::value, pair&&, __nonesuch_no_braces&&>::type __p) noexcept(__and_, - is_nothrow_move_assignable<_T2>>::value) + is_nothrow_move_assignable<_T2>>::value) { first = std::forward(__p.first); second = std::forward(__p.second); diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_queue.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_queue.h index c039db786e..60116c1b49 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_queue.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_queue.h @@ -302,6 +302,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // __cplusplus >= 201103L }; +#if __cpp_deduction_guides >= 201606 + template::value>> + queue(_Container) -> queue; + + template::value>, + typename = enable_if_t<__is_allocator<_Allocator>::value>> + queue(_Container, _Allocator) + -> queue; +#endif + /** * @brief Queue equality comparison. * @param __x A %queue. @@ -653,6 +665,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // __cplusplus >= 201103L }; +#if __cpp_deduction_guides >= 201606 + template::value>, + typename = enable_if_t::value>> + priority_queue(_Compare, _Container) + -> priority_queue; + + template::value_type, + typename _Compare = less<_ValT>, + typename _Container = vector<_ValT>, + typename = _RequireInputIter<_InputIterator>, + typename = enable_if_t::value>, + typename = enable_if_t::value>> + priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(), + _Container = _Container()) + -> priority_queue<_ValT, _Container, _Compare>; + + template::value>, + typename = enable_if_t::value>, + typename = enable_if_t<__is_allocator<_Allocator>::value>> + priority_queue(_Compare, _Container, _Allocator) + -> priority_queue; +#endif + // No equality/comparison operators are provided for priority_queue. #if __cplusplus >= 201103L diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_stack.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_stack.h index 8d343e6fb5..c83289a55c 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_stack.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_stack.h @@ -276,6 +276,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // __cplusplus >= 201103L }; +#if __cpp_deduction_guides >= 201606 + template::value>> + stack(_Container) -> stack; + + template::value>, + typename = enable_if_t<__is_allocator<_Allocator>::value>> + stack(_Container, _Allocator) + -> stack; +#endif + /** * @brief Stack equality comparison. * @param __x A %stack. diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_vector.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_vector.h index acec501bc1..129d45cd34 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_vector.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_vector.h @@ -1440,22 +1440,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Called by the second initialize_dispatch above template void - _M_range_initialize(_InputIterator __first, - _InputIterator __last, std::input_iterator_tag) + _M_range_initialize(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) { - for (; __first != __last; ++__first) + __try { + for (; __first != __last; ++__first) #if __cplusplus >= 201103L - emplace_back(*__first); + emplace_back(*__first); #else - push_back(*__first); + push_back(*__first); #endif + } __catch(...) { + clear(); + __throw_exception_again; + } } // Called by the second initialize_dispatch above template void - _M_range_initialize(_ForwardIterator __first, - _ForwardIterator __last, std::forward_iterator_tag) + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); this->_M_impl._M_start = this->_M_allocate(__n); diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/unique_ptr.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/unique_ptr.h index 4c99a9c0d9..8225e3a829 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/unique_ptr.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/unique_ptr.h @@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename = _DeleterConstraint<_Up>> constexpr unique_ptr() noexcept : _M_t() - { } + { } /** Takes ownership of a pointer. * @@ -233,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Creates a unique_ptr that owns nothing. template > - constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } + constexpr unique_ptr(nullptr_t) noexcept : _M_t() { } // Move constructors. @@ -458,7 +458,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename = _DeleterConstraint<_Up>> constexpr unique_ptr() noexcept : _M_t() - { } + { } /** Takes ownership of a pointer. * @@ -517,7 +517,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Creates a unique_ptr that owns nothing. template > - constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } + constexpr unique_ptr(nullptr_t) noexcept : _M_t() { } template>> diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/unordered_map.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/unordered_map.h index 07aad9e5e1..79ede69cee 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/unordered_map.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/unordered_map.h @@ -585,12 +585,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(value_type&& __x) { return _M_h.insert(std::move(__x)); } - template::value>::type> - std::pair + template + __enable_if_t::value, + pair> insert(_Pair&& __x) - { return _M_h.insert(std::forward<_Pair>(__x)); } + { return _M_h.emplace(std::forward<_Pair>(__x)); } //@} //@{ @@ -625,12 +624,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(const_iterator __hint, value_type&& __x) { return _M_h.insert(__hint, std::move(__x)); } - template::value>::type> - iterator + template + __enable_if_t::value, iterator> insert(const_iterator __hint, _Pair&& __x) - { return _M_h.insert(__hint, std::forward<_Pair>(__x)); } + { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); } //@} /** @@ -1560,12 +1557,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(value_type&& __x) { return _M_h.insert(std::move(__x)); } - template::value>::type> - iterator + template + __enable_if_t::value, iterator> insert(_Pair&& __x) - { return _M_h.insert(std::forward<_Pair>(__x)); } + { return _M_h.emplace(std::forward<_Pair>(__x)); } //@} //@{ @@ -1598,12 +1593,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(const_iterator __hint, value_type&& __x) { return _M_h.insert(__hint, std::move(__x)); } - template::value>::type> - iterator + template + __enable_if_t::value, iterator> insert(const_iterator __hint, _Pair&& __x) - { return _M_h.insert(__hint, std::forward<_Pair>(__x)); } + { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); } //@} /** diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/valarray_array.h b/contrib/gcc-8.0/libstdc++-v3/include/bits/valarray_array.h index f1d2c43044..f3770df3e6 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/valarray_array.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/valarray_array.h @@ -152,7 +152,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { inline static void _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) - { __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); } + { + if (__b) + __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); + } }; template @@ -258,7 +261,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { inline static void _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) - { __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); } + { + if (__n != 0) + __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); + } }; // Copy a plain array __a[<__n>] into a play array __b[<>] @@ -335,17 +341,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // - // Compute the sum of elements in range [__f, __l) + // Compute the sum of elements in range [__f, __l) which must not be empty. // This is a naive algorithm. It suffers from cancelling. - // In the future try to specialize - // for _Tp = float, double, long double using a more accurate - // algorithm. + // In the future try to specialize for _Tp = float, double, long double + // using a more accurate algorithm. // template inline _Tp __valarray_sum(const _Tp* __f, const _Tp* __l) { - _Tp __r = _Tp(); + _Tp __r = *__f++; while (__f != __l) __r += *__f++; return __r; diff --git a/contrib/gcc-8.0/libstdc++-v3/include/bits/vector.tcc b/contrib/gcc-8.0/libstdc++-v3/include/bits/vector.tcc index fb6d7e0098..93f033008f 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/bits/vector.tcc +++ b/contrib/gcc-8.0/libstdc++-v3/include/bits/vector.tcc @@ -582,7 +582,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (__n != 0) { - size_type __size = size(); + const size_type __size = size(); size_type __navail = size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish); @@ -601,23 +601,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { const size_type __len = _M_check_len(__n, "vector::_M_default_append"); - const size_type __old_size = __size; pointer __new_start(this->_M_allocate(__len)); - pointer __new_finish(__new_start); + pointer __destroy_from = pointer(); __try { - __new_finish - = std::__uninitialized_move_if_noexcept_a - (this->_M_impl._M_start, this->_M_impl._M_finish, - __new_start, _M_get_Tp_allocator()); - __new_finish = - std::__uninitialized_default_n_a(__new_finish, __n, - _M_get_Tp_allocator()); + std::__uninitialized_default_n_a(__new_start + __size, + __n, _M_get_Tp_allocator()); + __destroy_from = __new_start + __size; + std::__uninitialized_move_if_noexcept_a( + this->_M_impl._M_start, this->_M_impl._M_finish, + __new_start, _M_get_Tp_allocator()); } __catch(...) { - std::_Destroy(__new_start, __new_finish, - _M_get_Tp_allocator()); + if (__destroy_from) + std::_Destroy(__destroy_from, __destroy_from + __n, + _M_get_Tp_allocator()); _M_deallocate(__new_start, __len); __throw_exception_again; } @@ -628,7 +627,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __new_start; - this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_finish = __new_start + __size + __n; this->_M_impl._M_end_of_storage = __new_start + __len; } } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/debug/map.h b/contrib/gcc-8.0/libstdc++-v3/include/debug/map.h index 414b4dc075..7a4e2bff01 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/debug/map.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/debug/map.h @@ -105,6 +105,7 @@ namespace __debug : _Base(__m, __a) { } map(map&& __m, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/debug/multimap.h b/contrib/gcc-8.0/libstdc++-v3/include/debug/multimap.h index 8d6358b303..9ee3809a57 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/debug/multimap.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/debug/multimap.h @@ -105,6 +105,7 @@ namespace __debug : _Base(__m, __a) { } multimap(multimap&& __m, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/debug/multiset.h b/contrib/gcc-8.0/libstdc++-v3/include/debug/multiset.h index 4e1406e93c..0be14d7fc2 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/debug/multiset.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/debug/multiset.h @@ -104,6 +104,7 @@ namespace __debug : _Base(__m, __a) { } multiset(multiset&& __m, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/debug/set.h b/contrib/gcc-8.0/libstdc++-v3/include/debug/set.h index a886860cea..7f24a83237 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/debug/set.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/debug/set.h @@ -104,6 +104,7 @@ namespace __debug : _Base(__x, __a) { } set(set&& __x, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__x._M_base()), __a)) ) : _Safe(std::move(__x._M_safe()), __a), _Base(std::move(__x._M_base()), __a) { } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/debug/string b/contrib/gcc-8.0/libstdc++-v3/include/debug/string index 2b3677b3f7..b1b374b9b5 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/debug/string +++ b/contrib/gcc-8.0/libstdc++-v3/include/debug/string @@ -565,7 +565,7 @@ template, insert(iterator __p, _InputIterator __first, _InputIterator __last) { typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; - __glibcxx_check_insert_range2(__p, __first, __last, __dist); + __glibcxx_check_insert_range(__p, __first, __last, __dist); if (__dist.second >= __dp_sign) _Base::insert(__p.base(), __gnu_debug::__unsafe(__first), diff --git a/contrib/gcc-8.0/libstdc++-v3/include/experimental/algorithm b/contrib/gcc-8.0/libstdc++-v3/include/experimental/algorithm index fde4f347f8..4c51efb1c9 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/experimental/algorithm +++ b/contrib/gcc-8.0/libstdc++-v3/include/experimental/algorithm @@ -35,6 +35,7 @@ #include #include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -42,7 +43,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace experimental { -inline namespace fundamentals_v1 +inline namespace fundamentals_v2 { template inline _ForwardIterator @@ -79,7 +80,23 @@ inline namespace fundamentals_v1 __d, std::forward<_UniformRandomNumberGenerator>(__g)); } -} // namespace fundamentals_v1 + + template + inline _SampleIterator + sample(_PopulationIterator __first, _PopulationIterator __last, + _SampleIterator __out, _Distance __n) + { + return experimental::sample(__first, __last, __out, __n, + _S_randint_engine()); + } + + template + inline void + shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::shuffle(__first, __last, _S_randint_engine()); } + +} // namespace fundamentals_v2 } // namespace experimental _GLIBCXX_END_NAMESPACE_VERSION diff --git a/contrib/gcc-8.0/libstdc++-v3/include/experimental/memory_resource b/contrib/gcc-8.0/libstdc++-v3/include/experimental/memory_resource index b8480c2a17..23653ee2fe 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/experimental/memory_resource +++ b/contrib/gcc-8.0/libstdc++-v3/include/experimental/memory_resource @@ -33,7 +33,6 @@ #include #include #include -#include #include namespace std { @@ -258,6 +257,22 @@ namespace pmr { template class __resource_adaptor_imp : public memory_resource { + static_assert(is_same::value_type>::value, + "Allocator's value_type is char"); + static_assert(is_same::pointer>::value, + "Allocator's pointer type is value_type*"); + static_assert(is_same::const_pointer>::value, + "Allocator's const_pointer type is value_type const*"); + static_assert(is_same::void_pointer>::value, + "Allocator's void_pointer type is void*"); + static_assert(is_same::const_void_pointer>::value, + "Allocator's const_void_pointer type is void const*"); + public: using allocator_type = _Alloc; @@ -276,7 +291,7 @@ namespace pmr { __resource_adaptor_imp& operator=(const __resource_adaptor_imp&) = default; - allocator_type get_allocator() const { return _M_alloc; } + allocator_type get_allocator() const noexcept { return _M_alloc; } protected: virtual void* @@ -311,13 +326,13 @@ namespace pmr { private: // Calculate Aligned Size // Returns a size that is larger than or equal to __size and divisible - // by __alignment, where __alignment is required to be the power of 2. + // by __alignment, where __alignment is required to be a power of 2. static size_t _S_aligned_size(size_t __size, size_t __alignment) { return ((__size - 1)|(__alignment - 1)) + 1; } // Determine whether alignment meets one of those preconditions: - // 1. Equals to Zero + // 1. Equal to Zero // 2. Is power of two static bool _S_supported (size_t __x) @@ -327,47 +342,50 @@ namespace pmr { }; // Global memory resources - inline std::atomic& - __get_default_resource() - { - static atomic _S_default_resource(new_delete_resource()); - return _S_default_resource; - } inline memory_resource* new_delete_resource() noexcept { - static resource_adaptor> __r; - return static_cast(&__r); + using type = resource_adaptor>; + alignas(type) static unsigned char __buf[sizeof(type)]; + static type* __r = new(__buf) type; + return __r; } - template - class __null_memory_resource : private memory_resource + inline memory_resource* + null_memory_resource() noexcept + { + class type final : public memory_resource { - protected: void* - do_allocate(size_t, size_t) + do_allocate(size_t, size_t) override { std::__throw_bad_alloc(); } void - do_deallocate(void*, size_t, size_t) noexcept + do_deallocate(void*, size_t, size_t) noexcept override { } bool - do_is_equal(const memory_resource& __other) const noexcept + do_is_equal(const memory_resource& __other) const noexcept override { return this == &__other; } - - friend memory_resource* null_memory_resource() noexcept; }; - inline memory_resource* - null_memory_resource() noexcept - { - static __null_memory_resource __r; - return static_cast(&__r); + alignas(type) static unsigned char __buf[sizeof(type)]; + static type* __r = new(__buf) type; + return __r; } // The default memory resource + + inline std::atomic& + __get_default_resource() + { + using type = atomic; + alignas(type) static unsigned char __buf[sizeof(type)]; + static type* __r = new(__buf) type(new_delete_resource()); + return *__r; + } + inline memory_resource* get_default_resource() noexcept { return __get_default_resource().load(); } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/experimental/regex b/contrib/gcc-8.0/libstdc++-v3/include/experimental/regex index 253231f5c6..633b396b31 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/experimental/regex +++ b/contrib/gcc-8.0/libstdc++-v3/include/experimental/regex @@ -44,10 +44,9 @@ namespace experimental { inline namespace fundamentals_v2 { +#if _GLIBCXX_USE_CXX11_ABI namespace pmr { -_GLIBCXX_BEGIN_NAMESPACE_CXX11 - template using match_results = std::match_results<_BidirectionalIterator, polymorphic_allocator< @@ -58,9 +57,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 typedef match_results smatch; typedef match_results wsmatch; -_GLIBCXX_END_NAMESPACE_CXX11 } // namespace pmr - +#endif } // namespace fundamentals_v2 } // namespace experimental _GLIBCXX_END_NAMESPACE_VERSION diff --git a/contrib/gcc-8.0/libstdc++-v3/include/experimental/string b/contrib/gcc-8.0/libstdc++-v3/include/experimental/string index b340e2bcd9..5a96bf78d7 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/experimental/string +++ b/contrib/gcc-8.0/libstdc++-v3/include/experimental/string @@ -62,9 +62,9 @@ inline namespace fundamentals_v2 __cont.end()); } - namespace pmr { - _GLIBCXX_BEGIN_NAMESPACE_CXX11 - +#if _GLIBCXX_USE_CXX11_ABI + namespace pmr + { // basic_string using polymorphic allocator in namespace pmr template> using basic_string = @@ -77,8 +77,8 @@ inline namespace fundamentals_v2 typedef basic_string u32string; typedef basic_string wstring; - _GLIBCXX_END_NAMESPACE_CXX11 } // namespace pmr +#endif } // namespace fundamentals_v2 } // namespace experimental diff --git a/contrib/gcc-8.0/libstdc++-v3/include/experimental/string_view b/contrib/gcc-8.0/libstdc++-v3/include/experimental/string_view index e42d5acde7..2bbd9aa8a0 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/experimental/string_view +++ b/contrib/gcc-8.0/libstdc++-v3/include/experimental/string_view @@ -273,7 +273,7 @@ inline namespace fundamentals_v1 // [string.view.ops], string operations: constexpr basic_string_view - substr(size_type __pos, size_type __n=npos) const + substr(size_type __pos = 0, size_type __n = npos) const { return __pos <= this->_M_len ? basic_string_view{this->_M_str + __pos, diff --git a/contrib/gcc-8.0/libstdc++-v3/include/ext/aligned_buffer.h b/contrib/gcc-8.0/libstdc++-v3/include/ext/aligned_buffer.h index 81fb797723..2fc8f12e62 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/ext/aligned_buffer.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/ext/aligned_buffer.h @@ -49,6 +49,8 @@ namespace __gnu_cxx // Target macro ADJUST_FIELD_ALIGN can produce different alignment for // types when used as class members. __aligned_membuf is intended // for use as a class member, so align the buffer as for a class member. + // Since GCC 8 we could just use alignof(_Tp) instead, but older + // versions of non-GNU compilers might still need this trick. struct _Tp2 { _Tp _M_t; }; alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)]; @@ -86,11 +88,10 @@ namespace __gnu_cxx // This type is still used to avoid an ABI change. template struct __aligned_buffer - : std::aligned_storage::value> + : std::aligned_storage { typename - std::aligned_storage::value>::type - _M_storage; + std::aligned_storage::type _M_storage; __aligned_buffer() = default; diff --git a/contrib/gcc-8.0/libstdc++-v3/include/ext/pointer.h b/contrib/gcc-8.0/libstdc++-v3/include/ext/pointer.h index 318fbb11b0..e37d3a9bd8 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/ext/pointer.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/ext/pointer.h @@ -437,6 +437,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int); _CXX_POINTER_ARITH_OPERATOR_SET(long); _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long); +#ifdef _GLIBCXX_USE_LONG_LONG + _CXX_POINTER_ARITH_OPERATOR_SET(long long); + _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long long); +#endif // Mathematical Manipulators inline _Pointer_adapter& diff --git a/contrib/gcc-8.0/libstdc++-v3/include/ext/random b/contrib/gcc-8.0/libstdc++-v3/include/ext/random index 0a98b35092..8ae3bde777 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/ext/random +++ b/contrib/gcc-8.0/libstdc++-v3/include/ext/random @@ -3778,8 +3778,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx -#include "ext/opt_random.h" -#include "random.tcc" +#include +#include #endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C diff --git a/contrib/gcc-8.0/libstdc++-v3/include/ext/vstring.h b/contrib/gcc-8.0/libstdc++-v3/include/ext/vstring.h index 605311e9a2..e45e774e82 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/ext/vstring.h +++ b/contrib/gcc-8.0/libstdc++-v3/include/ext/vstring.h @@ -2962,6 +2962,6 @@ _GLIBCXX_END_NAMESPACE_VERSION #endif // C++11 -#include "vstring.tcc" +#include #endif /* _VSTRING_H */ diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/chrono b/contrib/gcc-8.0/libstdc++-v3/include/std/chrono index b3a0cb2087..1daca8700f 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/chrono +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/chrono @@ -275,15 +275,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct duration_values { static constexpr _Rep - zero() + zero() noexcept { return _Rep(0); } static constexpr _Rep - max() + max() noexcept { return numeric_limits<_Rep>::max(); } static constexpr _Rep - min() + min() noexcept { return numeric_limits<_Rep>::lowest(); } }; @@ -325,8 +325,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION duration(const duration&) = default; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3050. Conversion specification problem in chrono::duration template, + is_convertible, __or_<__is_float, __not_<__is_float<_Rep2>>>>> constexpr explicit duration(const _Rep2& __rep) : __r(static_cast(__rep)) { } @@ -428,15 +430,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 20.11.5.4 special values static constexpr duration - zero() + zero() noexcept { return duration(duration_values::zero()); } static constexpr duration - min() + min() noexcept { return duration(duration_values::min()); } static constexpr duration - max() + max() noexcept { return duration(duration_values::max()); } private: @@ -471,10 +473,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // SFINAE helper to obtain common_type<_Rep1, _Rep2> only if _Rep2 // is implicitly convertible to it. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3050. Conversion specification problem in chrono::duration constructor template::type> - using __common_rep_t - = typename enable_if::value, _CRep>::type; + using __common_rep_t = typename + enable_if::value, _CRep>::type; template constexpr duration<__common_rep_t<_Rep1, _Rep2>, _Period> @@ -652,11 +656,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // special values static constexpr time_point - min() + min() noexcept { return time_point(duration::min()); } static constexpr time_point - max() + max() noexcept { return time_point(duration::max()); } private: diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/functional b/contrib/gcc-8.0/libstdc++-v3/include/std/functional index 2b46ba899d..093528bcc4 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/functional +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/functional @@ -864,7 +864,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template \ decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \ operator()(_Args&&... __args) _QUALS \ - noexcept(noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ + noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \ + && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ { \ return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn), \ std::forward<_Args>(__args)...); \ diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/iomanip b/contrib/gcc-8.0/libstdc++-v3/include/std/iomanip index db8670ed56..9c1f63edb6 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/iomanip +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/iomanip @@ -446,7 +446,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __is; } -#if __cplusplus > 201103L +#if __cplusplus >= 201402L #define __cpp_lib_quoted_string_io 201304 @@ -471,8 +471,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) { return __detail::_Quoted_string< - const basic_string<_CharT, _Traits, _Alloc>&, _CharT>( - __string, __delim, __escape); + const basic_string<_CharT, _Traits, _Alloc>&, _CharT>( + __string, __delim, __escape); } template @@ -481,11 +481,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) { return __detail::_Quoted_string< - basic_string<_CharT, _Traits, _Alloc>&, _CharT>( - __string, __delim, __escape); + basic_string<_CharT, _Traits, _Alloc>&, _CharT>( + __string, __delim, __escape); } -#endif // __cplusplus > 201103L +#if __cplusplus >= 201703L + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2785. quoted should work with basic_string_view + template + inline auto + quoted(basic_string_view<_CharT, _Traits> __sv, + _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) + { + return __detail::_Quoted_string< + basic_string_view<_CharT, _Traits>, _CharT>(__sv, __delim, __escape); + } +#endif // C++17 +#endif // C++14 #endif // __cplusplus >= 201103L diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/optional b/contrib/gcc-8.0/libstdc++-v3/include/std/optional index 0aa20dd943..c40812f5e5 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/optional +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/optional @@ -82,8 +82,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: bad_optional_access() { } + virtual const char* what() const noexcept override - {return "bad optional access";} + { return "bad optional access"; } virtual ~bad_optional_access() noexcept = default; }; @@ -101,48 +102,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Payload for optionals with non-trivial destructor. template ::value, - bool /*_HasTrivialCopyAssignment*/ = - is_trivially_copy_assignable<_Tp>::value, - bool /*_HasTrivialMoveAssignment*/ = - is_trivially_move_assignable<_Tp>::value> + is_trivially_destructible_v<_Tp>, + bool /*_HasTrivialCopy */ = + is_trivially_copy_assignable_v<_Tp> + && is_trivially_copy_constructible_v<_Tp>, + bool /*_HasTrivialMove */ = + is_trivially_move_assignable_v<_Tp> + && is_trivially_move_constructible_v<_Tp>> struct _Optional_payload { - constexpr _Optional_payload() - : _M_empty() {} + constexpr _Optional_payload() noexcept : _M_empty() { } template - constexpr _Optional_payload(in_place_t, _Args&&... __args) - : _M_payload(std::forward<_Args>(__args)...), - _M_engaged(true) {} + constexpr + _Optional_payload(in_place_t, _Args&&... __args) + : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template - constexpr _Optional_payload(std::initializer_list<_Up> __il, - _Args&&... __args) + constexpr + _Optional_payload(std::initializer_list<_Up> __il, + _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), - _M_engaged(true) {} + _M_engaged(true) + { } + constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) - : _Optional_payload(__other) - {} + : _Optional_payload(__other) + { } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) - : _Optional_payload(std::move(__other)) - {} + : _Optional_payload(std::move(__other)) + { } - constexpr _Optional_payload(const _Optional_payload& __other) + constexpr + _Optional_payload(const _Optional_payload& __other) { if (__other._M_engaged) this->_M_construct(__other._M_payload); } - constexpr _Optional_payload(_Optional_payload&& __other) + constexpr + _Optional_payload(_Optional_payload&& __other) { if (__other._M_engaged) this->_M_construct(std::move(__other._M_payload)); } + constexpr _Optional_payload& operator=(const _Optional_payload& __other) { @@ -158,6 +166,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, @@ -176,7 +185,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } using _Stored_type = remove_const_t<_Tp>; + struct _Empty_byte { }; + union { _Empty_byte _M_empty; _Stored_type _M_payload; @@ -201,18 +212,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& - _M_get() noexcept - { - return this->_M_payload; - } + _M_get() noexcept + { return this->_M_payload; } constexpr const _Tp& - _M_get() const noexcept - { - return this->_M_payload; - } + _M_get() const noexcept + { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. + constexpr void _M_reset() noexcept { @@ -224,122 +232,104 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; - // Payload for constexpr optionals. + // Payload for potentially-constexpr optionals. template struct _Optional_payload<_Tp, true, true, true> { - constexpr _Optional_payload() - : _M_empty(), _M_engaged(false) {} + constexpr _Optional_payload() noexcept + : _M_empty(), _M_engaged(false) { } template - constexpr _Optional_payload(in_place_t, _Args&&... __args) - : _M_payload(std::forward<_Args>(__args)...), - _M_engaged(true) - {} + constexpr + _Optional_payload(in_place_t, _Args&&... __args) + : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) + { } template - constexpr _Optional_payload(std::initializer_list<_Up> __il, - _Args&&... __args) + constexpr + _Optional_payload(std::initializer_list<_Up> __il, + _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), - _M_engaged(true) {} - - template struct __ctor_tag {}; - - constexpr _Optional_payload(__ctor_tag, - const _Tp& __other) - : _M_payload(__other), _M_engaged(true) - {} + { } - constexpr _Optional_payload(__ctor_tag) - : _M_empty(), _M_engaged(false) - {} + constexpr + _Optional_payload(bool __engaged, const _Optional_payload& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(__other._M_get()); + } - constexpr _Optional_payload(__ctor_tag, _Tp&& __other) - : _M_payload(std::move(__other)), - _M_engaged(true) - {} - - constexpr _Optional_payload(bool __engaged, - const _Optional_payload& __other) - : _Optional_payload(__engaged ? - _Optional_payload(__ctor_tag{}, - __other._M_payload) : - _Optional_payload(__ctor_tag{})) - {} - - constexpr _Optional_payload(bool __engaged, - _Optional_payload&& __other) - : _Optional_payload(__engaged - ? _Optional_payload(__ctor_tag{}, - std::move(__other._M_payload)) - : _Optional_payload(__ctor_tag{})) - {} + constexpr + _Optional_payload(bool __engaged, _Optional_payload&& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(std::move(__other._M_get())); + } using _Stored_type = remove_const_t<_Tp>; + struct _Empty_byte { }; + union { - _Empty_byte _M_empty; + _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; + + // The _M_get operations have _M_engaged as a precondition. + constexpr _Tp& + _M_get() noexcept + { return this->_M_payload; } + + constexpr const _Tp& + _M_get() const noexcept + { return this->_M_payload; } }; // Payload for optionals with non-trivial copy assignment. template struct _Optional_payload<_Tp, true, false, true> { - constexpr _Optional_payload() - : _M_empty(), _M_engaged(false) {} + constexpr _Optional_payload() noexcept + : _M_empty(), _M_engaged(false) { } template - constexpr _Optional_payload(in_place_t, _Args&&... __args) - : _M_payload(std::forward<_Args>(__args)...), - _M_engaged(true) - {} + constexpr + _Optional_payload(in_place_t, _Args&&... __args) + : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) + { } template - constexpr _Optional_payload(std::initializer_list<_Up> __il, - _Args&&... __args) + constexpr + _Optional_payload(std::initializer_list<_Up> __il, + _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), - _M_engaged(true) {} - - template struct __ctor_tag {}; - - constexpr _Optional_payload(__ctor_tag, - const _Tp& __other) - : _M_payload(__other), _M_engaged(true) - {} + { } - constexpr _Optional_payload(__ctor_tag) - : _M_empty(), _M_engaged(false) - {} + constexpr + _Optional_payload(bool __engaged, const _Optional_payload& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(__other._M_get()); + } - constexpr _Optional_payload(__ctor_tag, _Tp&& __other) - : _M_payload(std::move(__other)), - _M_engaged(true) - {} - - constexpr _Optional_payload(bool __engaged, - const _Optional_payload& __other) - : _Optional_payload(__engaged ? - _Optional_payload(__ctor_tag{}, - __other._M_payload) : - _Optional_payload(__ctor_tag{})) - {} - - constexpr _Optional_payload(bool __engaged, - _Optional_payload&& __other) - : _Optional_payload(__engaged - ? _Optional_payload(__ctor_tag{}, - std::move(__other._M_payload)) - : _Optional_payload(__ctor_tag{})) - {} + constexpr + _Optional_payload(bool __engaged, _Optional_payload&& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(std::move(__other._M_get())); + } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; + constexpr _Optional_payload& operator=(const _Optional_payload& __other) { @@ -359,7 +349,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(_Optional_payload&& __other) = default; using _Stored_type = remove_const_t<_Tp>; + struct _Empty_byte { }; + union { _Empty_byte _M_empty; _Stored_type _M_payload; @@ -378,18 +370,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& - _M_get() noexcept - { - return this->_M_payload; - } + _M_get() noexcept + { return this->_M_payload; } constexpr const _Tp& - _M_get() const noexcept - { - return this->_M_payload; - } + _M_get() const noexcept + { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. + constexpr void _M_reset() noexcept { @@ -405,53 +394,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct _Optional_payload<_Tp, true, true, false> { - constexpr _Optional_payload() - : _M_empty(), _M_engaged(false) {} + constexpr _Optional_payload() noexcept + : _M_empty(), _M_engaged(false) { } template - constexpr _Optional_payload(in_place_t, _Args&&... __args) + constexpr + _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) - {} + { } template - constexpr _Optional_payload(std::initializer_list<_Up> __il, - _Args&&... __args) + constexpr + _Optional_payload(std::initializer_list<_Up> __il, + _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), - _M_engaged(true) {} - - template struct __ctor_tag {}; - - constexpr _Optional_payload(__ctor_tag, - const _Tp& __other) - : _M_payload(__other), _M_engaged(true) - {} + { } - constexpr _Optional_payload(__ctor_tag) - : _M_empty(), _M_engaged(false) - {} + constexpr + _Optional_payload(bool __engaged, const _Optional_payload& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(__other._M_get()); + } - constexpr _Optional_payload(__ctor_tag, _Tp&& __other) - : _M_payload(std::move(__other)), - _M_engaged(true) - {} - - constexpr _Optional_payload(bool __engaged, - const _Optional_payload& __other) - : _Optional_payload(__engaged ? - _Optional_payload(__ctor_tag{}, - __other._M_payload) : - _Optional_payload(__ctor_tag{})) - {} - - constexpr _Optional_payload(bool __engaged, - _Optional_payload&& __other) - : _Optional_payload(__engaged - ? _Optional_payload(__ctor_tag{}, - std::move(__other._M_payload)) - : _Optional_payload(__ctor_tag{})) - {} + constexpr + _Optional_payload(bool __engaged, _Optional_payload&& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(std::move(__other._M_get())); + } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; @@ -459,6 +434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Optional_payload& operator=(const _Optional_payload& __other) = default; + constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, @@ -477,7 +453,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } using _Stored_type = remove_const_t<_Tp>; + struct _Empty_byte { }; + union { _Empty_byte _M_empty; _Stored_type _M_payload; @@ -496,18 +474,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& - _M_get() noexcept - { - return this->_M_payload; - } + _M_get() noexcept + { return this->_M_payload; } constexpr const _Tp& - _M_get() const noexcept - { - return this->_M_payload; - } + _M_get() const noexcept + { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. + constexpr void _M_reset() noexcept { @@ -523,57 +498,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct _Optional_payload<_Tp, true, false, false> { - constexpr _Optional_payload() - : _M_empty(), _M_engaged(false) {} + constexpr _Optional_payload() noexcept + : _M_empty(), _M_engaged(false) {} template - constexpr _Optional_payload(in_place_t, _Args&&... __args) + constexpr + _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) - {} + { } template - constexpr _Optional_payload(std::initializer_list<_Up> __il, - _Args&&... __args) + constexpr + _Optional_payload(std::initializer_list<_Up> __il, + _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), - _M_engaged(true) {} - - template struct __ctor_tag {}; - - constexpr _Optional_payload(__ctor_tag, - const _Tp& __other) - : _M_payload(__other), _M_engaged(true) - {} + { } - constexpr _Optional_payload(__ctor_tag) - : _M_empty(), _M_engaged(false) - {} + constexpr + _Optional_payload(bool __engaged, const _Optional_payload& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(__other._M_get()); + } - constexpr _Optional_payload(__ctor_tag, _Tp&& __other) - : _M_payload(std::move(__other)), - _M_engaged(true) - {} - - constexpr _Optional_payload(bool __engaged, - const _Optional_payload& __other) - : _Optional_payload(__engaged ? - _Optional_payload(__ctor_tag{}, - __other._M_payload) : - _Optional_payload(__ctor_tag{})) - {} - - constexpr _Optional_payload(bool __engaged, - _Optional_payload&& __other) - : _Optional_payload(__engaged - ? _Optional_payload(__ctor_tag{}, - std::move(__other._M_payload)) - : _Optional_payload(__ctor_tag{})) - {} + constexpr + _Optional_payload(bool __engaged, _Optional_payload&& __other) + : _M_engaged(__engaged) + { + if (__engaged) + _M_construct(std::move(__other._M_get())); + } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; + constexpr _Optional_payload& operator=(const _Optional_payload& __other) { @@ -589,6 +551,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, @@ -607,7 +570,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } using _Stored_type = remove_const_t<_Tp>; + struct _Empty_byte { }; + union { _Empty_byte _M_empty; _Stored_type _M_payload; @@ -626,18 +591,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& - _M_get() noexcept - { - return this->_M_payload; - } + _M_get() noexcept + { return this->_M_payload; } constexpr const _Tp& - _M_get() const noexcept - { - return this->_M_payload; - } + _M_get() const noexcept + { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. + constexpr void _M_reset() noexcept { @@ -658,15 +620,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // The _M_construct operation has !_M_engaged as a precondition // while _M_destruct has _M_engaged as a precondition. template - void - _M_construct(_Args&&... __args) + void + _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) - { - ::new - (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload)) - _Stored_type(std::forward<_Args>(__args)...); - static_cast<_Dp*>(this)->_M_payload._M_engaged = true; - } + { + ::new + (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload)) + _Stored_type(std::forward<_Args>(__args)...); + static_cast<_Dp*>(this)->_M_payload._M_engaged = true; + } void _M_destruct() noexcept @@ -676,6 +638,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // _M_reset is a 'safe' operation with no precondition. + constexpr void _M_reset() noexcept { @@ -700,8 +663,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; - public: + public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; @@ -1217,6 +1180,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator->() const { return std::__addressof(this->_M_get()); } + constexpr _Tp* operator->() { return std::__addressof(this->_M_get()); } diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/string_view b/contrib/gcc-8.0/libstdc++-v3/include/std/string_view index 9f39df853e..96962e39bf 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/string_view +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/string_view @@ -235,14 +235,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_string_len(__str, __n); __pos = _M_check(__pos, "basic_string_view::copy"); const size_type __rlen = std::min(__n, _M_len - __pos); - for (auto __begin = this->_M_str + __pos, - __end = __begin + __rlen; __begin != __end;) - *__str++ = *__begin++; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2777. basic_string_view::copy should use char_traits::copy + traits_type::copy(__str, data() + __pos, __rlen); return __rlen; } constexpr basic_string_view - substr(size_type __pos, size_type __n = npos) const noexcept(false) + substr(size_type __pos = 0, size_type __n = npos) const noexcept(false) { __pos = _M_check(__pos, "basic_string_view::substr"); const size_type __rlen = std::min(__n, _M_len - __pos); diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/thread b/contrib/gcc-8.0/libstdc++-v3/include/std/thread index 1cabd6ae0e..8dba04fa8f 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/thread +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/thread @@ -102,21 +102,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: id _M_id; - public: - thread() noexcept = default; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2097. packaged_task constructors should be constrained - thread(thread&) = delete; - thread(const thread&) = delete; - thread(const thread&&) = delete; + template + using __not_same = __not_::type>::type, + thread>>; - thread(thread&& __t) noexcept - { swap(__t); } + public: + thread() noexcept = default; - template + template>> explicit thread(_Callable&& __f, _Args&&... __args) { + static_assert( __is_invocable::type, + typename decay<_Args>::type...>::value, + "std::thread arguments must be invocable after conversion to rvalues" + ); + #ifdef GTHR_ACTIVE_PROXY // Create a reference to pthread_create, not just the gthr weak symbol. auto __depend = reinterpret_cast(&pthread_create); @@ -135,6 +140,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::terminate(); } + thread(const thread&) = delete; + + thread(thread&& __t) noexcept + { swap(__t); } + thread& operator=(const thread&) = delete; thread& operator=(thread&& __t) noexcept diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/type_traits b/contrib/gcc-8.0/libstdc++-v3/include/std/type_traits index 711d6c50dd..06c46ea312 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/type_traits +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/type_traits @@ -37,18 +37,6 @@ #include -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 -# if defined (__UINT_LEAST16_TYPE__) && defined(__UINT_LEAST32_TYPE__) -namespace std -{ - typedef __UINT_LEAST16_TYPE__ uint_least16_t; - typedef __UINT_LEAST32_TYPE__ uint_least32_t; -} -# else -# include -# endif -#endif - namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -1148,7 +1136,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// is_trivially_constructible template struct is_trivially_constructible - : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)> + : public __and_, __bool_constant< + __is_trivially_constructible(_Tp, _Args...)>>::type { }; /// is_trivially_default_constructible @@ -1171,21 +1160,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __is_implicitly_default_constructible_impl - : public __do_is_implicitly_default_constructible_impl - { - typedef decltype(__test(declval<_Tp>())) type; - }; + : public __do_is_implicitly_default_constructible_impl + { + typedef decltype(__test(declval<_Tp>())) type; + }; template struct __is_implicitly_default_constructible_safe - : public __is_implicitly_default_constructible_impl<_Tp>::type - { }; + : public __is_implicitly_default_constructible_impl<_Tp>::type + { }; template struct __is_implicitly_default_constructible - : public __and_, - __is_implicitly_default_constructible_safe<_Tp>> - { }; + : public __and_, + __is_implicitly_default_constructible_safe<_Tp>> + { }; /// is_trivially_copy_constructible @@ -1297,7 +1286,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// alignment_of template struct alignment_of - : public integral_constant { }; + : public integral_constant { }; /// rank template @@ -1576,12 +1565,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_unsigned { typedef unsigned long long __type; }; -#if defined(_GLIBCXX_USE_WCHAR_T) && !defined(__WCHAR_UNSIGNED__) - template<> - struct __make_unsigned : __make_unsigned<__WCHAR_TYPE__> - { }; -#endif - #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> @@ -1686,21 +1669,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_signed { typedef signed long long __type; }; -#if defined(_GLIBCXX_USE_WCHAR_T) && defined(__WCHAR_UNSIGNED__) - template<> - struct __make_signed : __make_signed<__WCHAR_TYPE__> - { }; -#endif - -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - template<> - struct __make_signed : __make_signed - { }; - template<> - struct __make_signed : __make_signed - { }; -#endif - #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_signed @@ -2092,6 +2060,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __declval<_Tp>(0); } + // wchar_t, char16_t and char32_t are integral types but are neither + // signed integer types nor unsigned integer types, so must be + // transformed to the integer type with the smallest rank that has the + // same size and signedness. + // Use the partial specialization for enumeration types to do that, + // which means these explicit specializations must be defined after + // std::conditional has been defined. + +#if defined(_GLIBCXX_USE_WCHAR_T) + template<> + struct __make_unsigned + { + using __type + = typename __make_unsigned_selector::__type; + }; + + template<> + struct __make_signed + { + using __type + = typename __make_signed_selector::__type; + }; +#endif + + template<> + struct __make_unsigned + { + using __type + = typename __make_unsigned_selector::__type; + }; + + template<> + struct __make_signed + { + using __type + = typename __make_signed_selector::__type; + }; + + template<> + struct __make_unsigned + { + using __type + = typename __make_unsigned_selector::__type; + }; + + template<> + struct __make_signed + { + using __type + = typename __make_signed_selector::__type; + }; + + /// result_of template class result_of; @@ -2292,7 +2313,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public __invoke_result<_Functor, _ArgTypes...> { }; -#if __cplusplus > 201103L +#if __cplusplus >= 201402L /// Alias template for aligned_storage template::__type)> @@ -2324,11 +2345,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Alias template for result_of template using result_of_t = typename result_of<_Tp>::type; -#endif +#endif // C++14 + // __enable_if_t (std::enable_if_t for C++11) + template + using __enable_if_t = typename enable_if<_Cond, _Tp>::type; + + // __void_t (std::void_t for C++11) template using __void_t = void; -#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 +#if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++11 #define __cpp_lib_void_t 201411 /// A metafunction that always yields void, used for detecting valid types. template using void_t = void; diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/utility b/contrib/gcc-8.0/libstdc++-v3/include/std/utility index c9695006ff..a1cceceefb 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/utility +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/utility @@ -75,10 +75,6 @@ #include #include -#if __cplusplus > 201402L -#include -#endif - namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION diff --git a/contrib/gcc-8.0/libstdc++-v3/include/std/variant b/contrib/gcc-8.0/libstdc++-v3/include/std/variant index 48bec52840..6cef89852b 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/std/variant +++ b/contrib/gcc-8.0/libstdc++-v3/include/std/variant @@ -249,7 +249,7 @@ namespace __variant template void __erased_dtor(_Variant&& __v) - { std::_Destroy(std::__addressof(__get<_Np>(__v))); } + { std::_Destroy(std::__addressof(__variant::__get<_Np>(__v))); } template void @@ -506,6 +506,20 @@ namespace __variant } } + void _M_destructive_move(_Move_ctor_base&& __rhs) + { + this->~_Move_ctor_base(); + __try + { + ::new (this) _Move_ctor_base(std::move(__rhs)); + } + __catch (...) + { + this->_M_index = variant_npos; + __throw_exception_again; + } + } + _Move_ctor_base(const _Move_ctor_base&) = default; _Move_ctor_base& operator=(const _Move_ctor_base&) = default; _Move_ctor_base& operator=(_Move_ctor_base&&) = default; @@ -516,6 +530,12 @@ namespace __variant { using _Base = _Copy_ctor_alias<_Types...>; using _Base::_Base; + + void _M_destructive_move(_Move_ctor_base&& __rhs) + { + this->~_Move_ctor_base(); + ::new (this) _Move_ctor_base(std::move(__rhs)); + } }; template @@ -538,22 +558,14 @@ namespace __variant { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_assign<_Types&, const _Types&>... }; - _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); + _S_vtable[__rhs._M_index](this->_M_storage(), + __rhs._M_storage()); } } else { _Copy_assign_base __tmp(__rhs); - this->~_Copy_assign_base(); - __try - { - ::new (this) _Copy_assign_base(std::move(__tmp)); - } - __catch (...) - { - this->_M_index = variant_npos; - __throw_exception_again; - } + this->_M_destructive_move(std::move(__tmp)); } __glibcxx_assert(this->_M_index == __rhs._M_index); return *this; @@ -582,20 +594,6 @@ namespace __variant using _Base = _Copy_assign_alias<_Types...>; using _Base::_Base; - void _M_destructive_move(_Move_assign_base&& __rhs) - { - this->~_Move_assign_base(); - __try - { - ::new (this) _Move_assign_base(std::move(__rhs)); - } - __catch (...) - { - this->_M_index = variant_npos; - __throw_exception_again; - } - } - _Move_assign_base& operator=(_Move_assign_base&& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_move_assign) @@ -613,16 +611,7 @@ namespace __variant else { _Move_assign_base __tmp(std::move(__rhs)); - this->~_Move_assign_base(); - __try - { - ::new (this) _Move_assign_base(std::move(__tmp)); - } - __catch (...) - { - this->_M_index = variant_npos; - __throw_exception_again; - } + this->_M_destructive_move(std::move(__tmp)); } __glibcxx_assert(this->_M_index == __rhs._M_index); return *this; @@ -838,9 +827,8 @@ namespace __variant decltype(auto) static constexpr __visit_invoke(_Visitor&& __visitor, _Variants... __vars) { - return __invoke(std::forward<_Visitor>(__visitor), - std::get<__indices>( - std::forward<_Variants>(__vars))...); + return std::__invoke(std::forward<_Visitor>(__visitor), + std::get<__indices>(std::forward<_Variants>(__vars))...); } static constexpr auto @@ -1389,7 +1377,7 @@ namespace __variant using _Result_type = decltype(std::forward<_Visitor>(__visitor)( - get<0>(std::forward<_Variants>(__variants))...)); + std::get<0>(std::forward<_Variants>(__variants))...)); constexpr auto& __vtable = __detail::__variant::__gen_vtable< _Result_type, _Visitor&&, _Variants&&...>::_S_vtable; diff --git a/contrib/gcc-8.0/libstdc++-v3/include/tr1/cmath b/contrib/gcc-8.0/libstdc++-v3/include/tr1/cmath index d1df380412..c07dd5c73a 100644 --- a/contrib/gcc-8.0/libstdc++-v3/include/tr1/cmath +++ b/contrib/gcc-8.0/libstdc++-v3/include/tr1/cmath @@ -1160,10 +1160,6 @@ namespace tr1 using std::comp_ellint_3l; using std::comp_ellint_3; - using __gnu_cxx::conf_hypergf; - using __gnu_cxx::conf_hypergl; - using __gnu_cxx::conf_hyperg; - using std::cyl_bessel_if; using std::cyl_bessel_il; using std::cyl_bessel_i; @@ -1200,10 +1196,6 @@ namespace tr1 using std::hermitel; using std::hermite; - using __gnu_cxx::hypergf; - using __gnu_cxx::hypergl; - using __gnu_cxx::hyperg; - using std::laguerref; using std::laguerrel; using std::laguerre; @@ -1246,7 +1238,6 @@ _GLIBCXX_END_NAMESPACE_VERSION #include #include #include -#include #include #include #include @@ -1371,23 +1362,6 @@ namespace tr1 return __detail::__comp_ellint_3<__type>(__k, __nu); } - inline float - conf_hypergf(float __a, float __c, float __x) - { return __detail::__conf_hyperg(__a, __c, __x); } - - inline long double - conf_hypergl(long double __a, long double __c, long double __x) - { return __detail::__conf_hyperg(__a, __c, __x); } - - /// 5.2.1.7 Confluent hypergeometric functions. - template - inline typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type - conf_hyperg(_Tpa __a, _Tpc __c, _Tp __x) - { - typedef typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type __type; - return __detail::__conf_hyperg<__type>(__a, __c, __x); - } - inline float cyl_bessel_if(float __nu, float __x) { return __detail::__cyl_bessel_i(__nu, __x); } @@ -1541,23 +1515,6 @@ namespace tr1 return __detail::__poly_hermite<__type>(__n, __x); } - inline float - hypergf(float __a, float __b, float __c, float __x) - { return __detail::__hyperg(__a, __b, __c, __x); } - - inline long double - hypergl(long double __a, long double __b, long double __c, long double __x) - { return __detail::__hyperg(__a, __b, __c, __x); } - - /// 5.2.1.17 Hypergeometric functions. - template - inline typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type - hyperg(_Tpa __a, _Tpb __b, _Tpc __c, _Tp __x) - { - typedef typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type __type; - return __detail::__hyperg<__type>(__a, __b, __c, __x); - } - inline float laguerref(unsigned int __n, float __x) { return __detail::__laguerre(__n, __x); } @@ -1668,4 +1625,77 @@ namespace tr1 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std +#if _GLIBCXX_USE_STD_SPEC_FUNCS && !defined(__STRICT_ANSI__) +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace tr1 +{ + using __gnu_cxx::conf_hypergf; + using __gnu_cxx::conf_hypergl; + using __gnu_cxx::conf_hyperg; + + using __gnu_cxx::hypergf; + using __gnu_cxx::hypergl; + using __gnu_cxx::hyperg; +} // namespace tr1 + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#else // ! (_GLIBCXX_USE_STD_SPEC_FUNCS && !defined(__STRICT_ANSI__)) + +#include +#include +#include + +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace tr1 +{ + inline float + conf_hypergf(float __a, float __c, float __x) + { return __detail::__conf_hyperg(__a, __c, __x); } + + inline long double + conf_hypergl(long double __a, long double __c, long double __x) + { return __detail::__conf_hyperg(__a, __c, __x); } + + /// 5.2.1.7 Confluent hypergeometric functions. + template + inline typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type + conf_hyperg(_Tpa __a, _Tpc __c, _Tp __x) + { + typedef typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type __type; + return __detail::__conf_hyperg<__type>(__a, __c, __x); + } + + inline float + hypergf(float __a, float __b, float __c, float __x) + { return __detail::__hyperg(__a, __b, __c, __x); } + + inline long double + hypergl(long double __a, long double __b, long double __c, long double __x) + { return __detail::__hyperg(__a, __b, __c, __x); } + + /// 5.2.1.17 Hypergeometric functions. + template + inline typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type + hyperg(_Tpa __a, _Tpb __b, _Tpc __c, _Tp __x) + { + typedef typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type __type; + return __detail::__hyperg<__type>(__a, __b, __c, __x); + } + +} // namespace tr1 + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // _GLIBCXX_USE_STD_SPEC_FUNCS && !defined(__STRICT_ANSI__) + #endif // _GLIBCXX_TR1_CMATH diff --git a/contrib/gcc-8.0/libstdc++-v3/libsupc++/cxxabi_init_exception.h b/contrib/gcc-8.0/libstdc++-v3/libsupc++/cxxabi_init_exception.h index d973a087f1..e438c1008d 100644 --- a/contrib/gcc-8.0/libstdc++-v3/libsupc++/cxxabi_init_exception.h +++ b/contrib/gcc-8.0/libstdc++-v3/libsupc++/cxxabi_init_exception.h @@ -62,6 +62,9 @@ namespace __cxxabiv1 void* __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW; + void + __cxa_free_exception(void*) _GLIBCXX_NOTHROW; + // Initialize exception (this is a GNU extension) __cxa_refcounted_exception* __cxa_init_primary_exception(void *object, std::type_info *tinfo, diff --git a/contrib/gcc-8.0/libstdc++-v3/libsupc++/exception_ptr.h b/contrib/gcc-8.0/libstdc++-v3/libsupc++/exception_ptr.h index a927327214..bd355ed880 100644 --- a/contrib/gcc-8.0/libstdc++-v3/libsupc++/exception_ptr.h +++ b/contrib/gcc-8.0/libstdc++-v3/libsupc++/exception_ptr.h @@ -178,25 +178,31 @@ namespace std exception_ptr make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT { -#if __cpp_exceptions +#if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI + void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); + (void) __cxxabiv1::__cxa_init_primary_exception( + __e, const_cast(&typeid(__ex)), + __exception_ptr::__dest_thunk<_Ex>); try { -#if __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI - void *__e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); - (void)__cxxabiv1::__cxa_init_primary_exception( - __e, const_cast(&typeid(__ex)), - __exception_ptr::__dest_thunk<_Ex>); ::new (__e) _Ex(__ex); return exception_ptr(__e); -#else + } + catch(...) + { + __cxxabiv1::__cxa_free_exception(__e); + return current_exception(); + } +#elif __cpp_exceptions + try + { throw __ex; -#endif } catch(...) { return current_exception(); } -#else +#else // no RTTI and no exceptions return exception_ptr(); #endif } diff --git a/contrib/gcc-8.0/libstdc++-v3/libsupc++/new_opa.cc b/contrib/gcc-8.0/libstdc++-v3/libsupc++/new_opa.cc index 097280d9b5..68eac5b8ce 100644 --- a/contrib/gcc-8.0/libstdc++-v3/libsupc++/new_opa.cc +++ b/contrib/gcc-8.0/libstdc++-v3/libsupc++/new_opa.cc @@ -25,20 +25,36 @@ #include #include +#include #include #include "new" +#if !_GLIBCXX_HAVE_ALIGNED_ALLOC && !_GLIBCXX_HAVE__ALIGNED_MALLOC \ + && !_GLIBCXX_HAVE_POSIX_MEMALIGN && _GLIBCXX_HAVE_MEMALIGN +# if _GLIBCXX_HOSTED && __has_include() +// Some C libraries declare memalign in +# include +# else +extern "C" void *memalign(std::size_t boundary, std::size_t size); +# endif +#endif + using std::new_handler; using std::bad_alloc; -#if !_GLIBCXX_HAVE_ALIGNED_ALLOC -#if _GLIBCXX_HAVE__ALIGNED_MALLOC -#define aligned_alloc(al,sz) _aligned_malloc(sz,al) +namespace __gnu_cxx { +#if _GLIBCXX_HAVE_ALIGNED_ALLOC +using ::aligned_alloc; +#elif _GLIBCXX_HAVE__ALIGNED_MALLOC +static inline void* +aligned_alloc (std::size_t al, std::size_t sz) +{ return _aligned_malloc(sz, al); } #elif _GLIBCXX_HAVE_POSIX_MEMALIGN static inline void* aligned_alloc (std::size_t al, std::size_t sz) { void *ptr; + // posix_memalign has additional requirement, not present on aligned_alloc: // The value of alignment shall be a power of two multiple of sizeof(void *). if (al < sizeof(void*)) al = sizeof(void*); @@ -48,25 +64,23 @@ aligned_alloc (std::size_t al, std::size_t sz) return nullptr; } #elif _GLIBCXX_HAVE_MEMALIGN -#if _GLIBCXX_HOSTED -#include -#else -extern "C" void *memalign(std::size_t boundary, std::size_t size); +static inline void* +aligned_alloc (std::size_t al, std::size_t sz) +{ +#ifdef __sun + // Solaris 10 memalign requires that alignment is greater than or equal to + // the size of a word. + if (al < sizeof(int)) + al = sizeof(int); #endif -#define aligned_alloc memalign -#else -#include + return memalign (al, sz); +} +#else // !HAVE__ALIGNED_MALLOC && !HAVE_POSIX_MEMALIGN && !HAVE_MEMALIGN // The C library doesn't provide any aligned allocation functions, define one. // This is a modified version of code from gcc/config/i386/gmm_malloc.h static inline void* aligned_alloc (std::size_t al, std::size_t sz) { - // Alignment must be a power of two. - if (al & (al - 1)) - return nullptr; - else if (!sz) - return nullptr; - // We need extra bytes to store the original value returned by malloc. if (al < sizeof(void*)) al = sizeof(void*); @@ -82,7 +96,7 @@ aligned_alloc (std::size_t al, std::size_t sz) return aligned_ptr; } #endif -#endif +} // namespace __gnu_cxx _GLIBCXX_WEAK_DEFINITION void * operator new (std::size_t sz, std::align_val_t al) @@ -90,16 +104,28 @@ operator new (std::size_t sz, std::align_val_t al) void *p; std::size_t align = (std::size_t)al; + /* Alignment must be a power of two. */ + /* XXX This should be checked by the compiler (PR 86878). */ + if (__builtin_expect (align & (align - 1), false)) + _GLIBCXX_THROW_OR_ABORT(bad_alloc()); + /* malloc (0) is unpredictable; avoid it. */ - if (sz == 0) + if (__builtin_expect (sz == 0, false)) sz = 1; #if _GLIBCXX_HAVE_ALIGNED_ALLOC +# ifdef _AIX + /* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement + * that alignment is a multiple of sizeof(void*). */ + if (align < sizeof(void*)) + align = sizeof(void*); +# endif /* C11: the value of size shall be an integral multiple of alignment. */ if (std::size_t rem = sz & (align - 1)) sz += align - rem; #endif + using __gnu_cxx::aligned_alloc; while (__builtin_expect ((p = aligned_alloc (align, sz)) == 0, false)) { new_handler handler = std::get_new_handler (); diff --git a/contrib/gcc-8.0/libstdc++-v3/src/c++11/codecvt.cc b/contrib/gcc-8.0/libstdc++-v3/src/c++11/codecvt.cc index 259de80775..3a1a825070 100644 --- a/contrib/gcc-8.0/libstdc++-v3/src/c++11/codecvt.cc +++ b/contrib/gcc-8.0/libstdc++-v3/src/c++11/codecvt.cc @@ -1086,7 +1086,12 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end, reinterpret_cast(__to), reinterpret_cast(__to_end) }; - auto res = ucs2_in(from, to, _M_maxcode, _M_mode); +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + codecvt_mode mode = {}; +#else + codecvt_mode mode = little_endian; +#endif + auto res = ucs2_in(from, to, _M_maxcode, mode); #elif __SIZEOF_WCHAR_T__ == 4 range to{ reinterpret_cast(__to), diff --git a/contrib/gcc-8.0/libstdc++-v3/src/c++11/string-inst.cc b/contrib/gcc-8.0/libstdc++-v3/src/c++11/string-inst.cc index 567d817dd7..47a1c9af3a 100644 --- a/contrib/gcc-8.0/libstdc++-v3/src/c++11/string-inst.cc +++ b/contrib/gcc-8.0/libstdc++-v3/src/c++11/string-inst.cc @@ -35,6 +35,12 @@ # define _GLIBCXX_USE_CXX11_ABI 1 #endif +// Prevent the basic_string(const _CharT*, const _Alloc&) and +// basic_string(size_type, _CharT, const _Alloc&) constructors from being +// replaced by constrained function templates, so that we instantiate the +// pre-C++17 definitions. +#define _GLIBCXX_DEFINING_STRING_INSTANTIATIONS 1 + #include // Instantiation configuration. diff --git a/contrib/gcc-8.0/libstdc++-v3/src/c++11/system_error.cc b/contrib/gcc-8.0/libstdc++-v3/src/c++11/system_error.cc index c6549fcb4e..07f44c0af9 100644 --- a/contrib/gcc-8.0/libstdc++-v3/src/c++11/system_error.cc +++ b/contrib/gcc-8.0/libstdc++-v3/src/c++11/system_error.cc @@ -29,6 +29,7 @@ #include #include #include +#include #undef __sso_string namespace @@ -65,6 +66,261 @@ namespace // _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc) return string(strerror(i)); } + + virtual std::error_condition + default_error_condition(int ev) const noexcept + { + switch (ev) + { + // List of errno macros from [cerrno.syn]. + // C11 only defines EDOM, EILSEQ and ERANGE, the rest are from POSIX. + // They expand to integer constant expressions with type int, + // and distinct positive values, suitable for use in #if directives. + // POSIX adds more macros (but they're not defined on all targets, + // see config/os/*/error_constants.h), and POSIX allows + // EAGAIN == EWOULDBLOCK and ENOTSUP == EOPNOTSUPP. + +#ifdef E2BIG + case E2BIG: +#endif +#ifdef EACCES + case EACCES: +#endif +#ifdef EADDRINUSE + case EADDRINUSE: +#endif +#ifdef EADDRNOTAVAIL + case EADDRNOTAVAIL: +#endif +#ifdef EAFNOSUPPORT + case EAFNOSUPPORT: +#endif +#ifdef EAGAIN + case EAGAIN: +#endif +#ifdef EALREADY + case EALREADY: +#endif +#ifdef EBADF + case EBADF: +#endif +#ifdef EBADMSG + case EBADMSG: +#endif +#ifdef EBUSY + case EBUSY: +#endif +#ifdef ECANCELED + case ECANCELED: +#endif +#ifdef ECHILD + case ECHILD: +#endif +#ifdef ECONNABORTED + case ECONNABORTED: +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED: +#endif +#ifdef ECONNRESET + case ECONNRESET: +#endif +#ifdef EDEADLK + case EDEADLK: +#endif +#ifdef EDESTADDRREQ + case EDESTADDRREQ: +#endif + case EDOM: +#ifdef EEXIST + case EEXIST: +#endif +#ifdef EFAULT + case EFAULT: +#endif +#ifdef EFBIG + case EFBIG: +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: +#endif +#ifdef EIDRM + case EIDRM: +#endif + case EILSEQ: +#ifdef EINPROGRESS + case EINPROGRESS: +#endif +#ifdef EINTR + case EINTR: +#endif +#ifdef EINVAL + case EINVAL: +#endif +#ifdef EIO + case EIO: +#endif +#ifdef EISCONN + case EISCONN: +#endif +#ifdef EISDIR + case EISDIR: +#endif +#ifdef ELOOP + case ELOOP: +#endif +#ifdef EMFILE + case EMFILE: +#endif +#ifdef EMLINK + case EMLINK: +#endif +#ifdef EMSGSIZE + case EMSGSIZE: +#endif +#ifdef ENAMETOOLONG + case ENAMETOOLONG: +#endif +#ifdef ENETDOWN + case ENETDOWN: +#endif +#ifdef ENETRESET + case ENETRESET: +#endif +#ifdef ENETUNREACH + case ENETUNREACH: +#endif +#ifdef ENFILE + case ENFILE: +#endif +#ifdef ENOBUFS + case ENOBUFS: +#endif +#ifdef ENODATA + case ENODATA: +#endif +#ifdef ENODEV + case ENODEV: +#endif +#ifdef ENOENT + case ENOENT: +#endif +#ifdef ENOEXEC + case ENOEXEC: +#endif +#ifdef ENOLCK + case ENOLCK: +#endif +#ifdef ENOLINK + case ENOLINK: +#endif +#ifdef ENOMEM + case ENOMEM: +#endif +#ifdef ENOMSG + case ENOMSG: +#endif +#ifdef ENOPROTOOPT + case ENOPROTOOPT: +#endif +#ifdef ENOSPC + case ENOSPC: +#endif +#ifdef ENOSR + case ENOSR: +#endif +#ifdef ENOSTR + case ENOSTR: +#endif +#ifdef ENOSYS + case ENOSYS: +#endif +#ifdef ENOTCONN + case ENOTCONN: +#endif +#ifdef ENOTDIR + case ENOTDIR: +#endif +#if defined ENOTEMPTY && (!defined EEXIST || ENOTEMPTY != EEXIST) + // AIX sometimes uses the same value for EEXIST and ENOTEMPTY + case ENOTEMPTY: +#endif +#ifdef ENOTRECOVERABLE + case ENOTRECOVERABLE: +#endif +#ifdef ENOTSOCK + case ENOTSOCK: +#endif +#ifdef ENOTSUP + case ENOTSUP: +#endif +#ifdef ENOTTY + case ENOTTY: +#endif +#ifdef ENXIO + case ENXIO: +#endif +#if defined EOPNOTSUPP && (!defined ENOTSUP || EOPNOTSUPP != ENOTSUP) + case EOPNOTSUPP: +#endif +#ifdef EOVERFLOW + case EOVERFLOW: +#endif +#ifdef EOWNERDEAD + case EOWNERDEAD: +#endif +#ifdef EPERM + case EPERM: +#endif +#ifdef EPIPE + case EPIPE: +#endif +#ifdef EPROTO + case EPROTO: +#endif +#ifdef EPROTONOSUPPORT + case EPROTONOSUPPORT: +#endif +#ifdef EPROTOTYPE + case EPROTOTYPE: +#endif + case ERANGE: +#ifdef EROFS + case EROFS: +#endif +#ifdef ESPIPE + case ESPIPE: +#endif +#ifdef ESRCH + case ESRCH: +#endif +#ifdef ETIME + case ETIME: +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: +#endif +#ifdef ETXTBSY + case ETXTBSY: +#endif +#if defined EWOULDBLOCK && (!defined EAGAIN || EWOULDBLOCK != EAGAIN) + case EWOULDBLOCK: +#endif +#ifdef EXDEV + case EXDEV: +#endif + return std::error_condition(ev, std::generic_category()); + + /* Additional system-dependent mappings from non-standard error codes + * to one of the POSIX values above would go here, e.g. + case EBLAH: + return std::error_condition(EINVAL, std::generic_category()); + */ + + default: + return std::error_condition(ev, std::system_category()); + } + } }; const generic_error_category generic_category_instance{}; -- 2.41.0