summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2013-08-30 10:24:49 +0200
committerMarek Polacek <polacek@redhat.com>2013-08-30 10:24:49 +0200
commit1a986fd51aa96fbd0d66f4d52739356374912563 (patch)
treef5310553e69c8a35180556d9af7e66bdecac7f92
parent61fb959b676db6ca9ef0da335dfef0d8ec08e113 (diff)
parentf85c9de6ba5165bc1b941ceb09e4e8ffb1c7eb0f (diff)
downloadgcc-ubsan.tar.gz
Merge branch 'master' of git+ssh://gcc.gnu.org/git/gcc into ubsanubsan
-rw-r--r--ChangeLog4
-rw-r--r--MAINTAINERS1
-rw-r--r--contrib/ChangeLog4
-rwxr-xr-xcontrib/gcc_update2
-rw-r--r--gcc/ChangeLog445
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in4
-rw-r--r--gcc/builtins.def2
-rw-r--r--gcc/cfgloop.h14
-rw-r--r--gcc/cgraph.c5
-rw-r--r--gcc/cgraphclones.c14
-rw-r--r--gcc/config/aarch64/arm_neon.h211
-rw-r--r--gcc/config/i386/driver-i386.c30
-rw-r--r--gcc/config/i386/i386.c8
-rw-r--r--gcc/config/i386/i386.md47
-rw-r--r--gcc/config/rx/rx.c6
-rwxr-xr-xgcc/configure1
-rw-r--r--gcc/configure.ac1
-rw-r--r--gcc/coverage.c44
-rw-r--r--gcc/cp/ChangeLog78
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/decl.c77
-rw-r--r--gcc/cp/error.c73
-rw-r--r--gcc/cp/except.c51
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/rtti.c4
-rw-r--r--gcc/cp/vtable-class-hierarchy.c102
-rw-r--r--gcc/doc/invoke.texi3
-rw-r--r--gcc/dumpfile.c10
-rw-r--r--gcc/dumpfile.h3
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-expr.c102
-rw-r--r--gcc/function.h8
-rw-r--r--gcc/gdbhooks.py397
-rw-r--r--gcc/gimple-pretty-print.c28
-rw-r--r--gcc/gimple.c4
-rw-r--r--gcc/gimple.def8
-rw-r--r--gcc/gimple.h26
-rw-r--r--gcc/gimplify.c200
-rw-r--r--gcc/go/ChangeLog6
-rw-r--r--gcc/go/go-gcc.cc16
-rw-r--r--gcc/gtm-builtins.def2
-rw-r--r--gcc/internal-fn.c24
-rw-r--r--gcc/internal-fn.def3
-rw-r--r--gcc/ipa-cp.c41
-rw-r--r--gcc/ipa-inline.c29
-rw-r--r--gcc/ipa-prop.c154
-rw-r--r--gcc/ipa-prop.h35
-rw-r--r--gcc/loop-unroll.c19
-rw-r--r--gcc/lto-section-in.c35
-rw-r--r--gcc/lto-streamer-out.c36
-rw-r--r--gcc/lto-streamer.h2
-rw-r--r--gcc/lto-symtab.c2
-rw-r--r--gcc/lto/ChangeLog22
-rw-r--r--gcc/lto/lto-partition.c32
-rw-r--r--gcc/lto/lto.c30
-rw-r--r--gcc/omp-low.c1320
-rw-r--r--gcc/pass_manager.h1
-rw-r--r--gcc/passes.c17
-rw-r--r--gcc/print-tree.c2
-rw-r--r--gcc/profile.c9
-rw-r--r--gcc/testsuite/ChangeLog155
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr58257.c15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/dc7.C7
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C2
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr50413.cc2
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr50819.cc2
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr56812.cc2
-rw-r--r--gcc/testsuite/gcc.dg/inline-dump.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr26570.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr32773.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr40209.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr57287-2.c35
-rw-r--r--gcc/testsuite/gcc.dg/pr58010.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57685.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58223.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58228.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58246.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/unroll_1.c2
-rw-r--r--gcc/testsuite/gcc.dg/unroll_2.c2
-rw-r--r--gcc/testsuite/gcc.dg/unroll_3.c2
-rw-r--r--gcc/testsuite/gcc.dg/unroll_4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-16.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-18.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-19.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-21.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-22.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-24.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-26.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-27.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-28.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-29.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-31.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8a.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8b.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-9.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr56933.c6
-rw-r--r--gcc/testsuite/gfortran.dg/realloc_on_assign_14.f902
-rw-r--r--gcc/testsuite/gfortran.dg/realloc_on_assign_19.f9021
-rw-r--r--gcc/tree-data-ref.c23
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-if-conv.c7
-rw-r--r--gcc/tree-inline.c5
-rw-r--r--gcc/tree-loop-distribution.c21
-rw-r--r--gcc/tree-parloops.c2
-rw-r--r--gcc/tree-pass.h12
-rw-r--r--gcc/tree-pretty-print.c36
-rw-r--r--gcc/tree-ssa-ccp.c16
-rw-r--r--gcc/tree-ssa-copy.c8
-rw-r--r--gcc/tree-ssa-dce.c5
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c10
-rw-r--r--gcc/tree-ssa-loop.c2
-rw-r--r--gcc/tree-ssa-threadedge.c8
-rw-r--r--gcc/tree-ssa-threadupdate.c49
-rw-r--r--gcc/tree-streamer-in.c20
-rw-r--r--gcc/tree-streamer-out.c20
-rw-r--r--gcc/tree-vect-data-refs.c114
-rw-r--r--gcc/tree-vect-loop-manip.c25
-rw-r--r--gcc/tree-vect-loop.c43
-rw-r--r--gcc/tree-vect-stmts.c145
-rw-r--r--gcc/tree-vectorizer.c271
-rw-r--r--gcc/tree-vectorizer.h4
-rw-r--r--gcc/tree-vrp.c12
-rw-r--r--gcc/tree.c28
-rw-r--r--gcc/tree.def4
-rw-r--r--gcc/tree.h50
-rw-r--r--gcc/value-prof.c14
-rw-r--r--libstdc++-v3/ChangeLog18
-rw-r--r--libstdc++-v3/include/bits/regex.h17
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.h2
-rw-r--r--libstdc++-v3/include/bits/regex_executor.h19
-rw-r--r--libstdc++-v3/include/bits/regex_executor.tcc3
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc48
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc53
-rw-r--r--libvtv/ChangeLog19
168 files changed, 4429 insertions, 1038 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e71eaf7375..2f8ddb7da40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-08-27 David Malcolm <dmalcolm@redhat.com>
+
+ * MAINTAINERS (gdbhooks.py): Add myself as maintainer.
+
2013-08-26 Caroline Tice <cmtice@google.com>
* MAINTAINERS: Correct earliers update: Move myself from libvtv
diff --git a/MAINTAINERS b/MAINTAINERS
index 51017c8bf2c..6d9a4cd3898 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -257,6 +257,7 @@ testsuite Rainer Orth ro@CeBiTec.Uni-Bielefeld.DE
testsuite Mike Stump mikestump@comcast.net
testsuite Janis Johnson janisjo@codesourcery.com
register allocation Vladimir Makarov vmakarov@redhat.com
+gdbhooks.py David Malcolm dmalcolm@redhat.com
Note that individuals who maintain parts of the compiler need approval to
check in changes outside of the parts of the compiler they maintain.
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 5728d582101..1b633fcc589 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,7 @@
+2013-08-29 Mike Stump <mikestump@comcast.net>
+
+ * gcc_update (configure): Update to handle svn 1.8.1.
+
2013-08-03 Caroline Tice4 <cmtice@google.com>
* gcc_update: Add libvtv files.
diff --git a/contrib/gcc_update b/contrib/gcc_update
index 70a5ef7d0e5..bdf89c4d128 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -385,7 +385,7 @@ case $vcs_type in
fi
revision=`$GCC_SVN info | awk '/Revision:/ { print $2 }'`
- branch=`$GCC_SVN info | sed -ne "/URL:/ {
+ branch=`$GCC_SVN info | sed -ne "/^URL:/ {
s,.*/trunk,trunk,
s,.*/branches/,,
s,.*/tags/,,
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index af6a6d8e88a..171988a5c5a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,333 @@
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (set_call_expr_flags): Fix handling of TM_PURE.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58228
+ * tree-vect-data-refs.c (vect_analyze_data_ref_access): Do not
+ allow invariant loads in nested loop vectorization.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58223
+ * tree-loop-distribution.c (has_anti_dependence): Rename to ...
+ (has_anti_or_output_dependence): ... this and adjust to also
+ look for output dependences.
+ (mark_nodes_having_upstream_mem_writes): Adjust.
+ (rdg_flag_uses): Likewise.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58010
+ * tree-vect-loop.c (vect_create_epilog_for_reduction): Remove
+ assert that we have a loop-closed PHI.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto-symtab.c (lto_cgraph_replace_node): Free decl_in_state.
+ * cgraph.c (cgraph_release_function_body): Free decl_in_state.
+ * lto-section-in.c (lto_free_function_in_decl_state): New function.
+ (lto_free_function_in_decl_state_for_node): New function.
+
+2013-08-29 Xinliang David Li <davidxl@google.com>
+
+ * loop-unroll.c (report_unroll_peel): Minor message
+ change.
+ * tree-vect-loop-manip.c (vect_do_peeling_for_alignment):
+ Emit alignment peeling message with default -fopt-info.
+ (vect_loop_versioning): Emit loop version info message.
+ * tree-vectorizer.c (vectorize_loops): Minor message
+ change.
+ (execute_vect_slp): Ditto.
+
+2013-08-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cgraphclones.c (cgraph_create_virtual_clone): Compute the DECL_NAME
+ of the clone from the DECL_NAME of the original function.
+
+2013-08-29 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * passes.c (register_pass): Add overload.
+ * tree-pass.h (register_pass): Forward declare it. Add comment.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto-streamer-out.c (hash_tree): Stream DECL_FINAL_P.
+ DECL_CXX_CONSTRUCTOR_P. DECL_CXX_DESTRUCTOR_P.
+ TYPE_FINAL_P.
+ * lto-streamer-in.c (unpack_ts_decl_with_vis_value_fields):
+ DECL_FINAL_P. DECL_CXX_CONSTRUCTOR_P and DECL_CXX_DESTRUCTOR_P.
+ (unpack_ts_type_common_value_fields): Stream TYPE_FINAL_P.
+ * tree-streamer-out.c (pack_ts_decl_with_vis_value_fields):
+ Add DECL_FINAL_P, DECL_CXX_CONSTRUCTOR_P, DECL_CXX_DESTRUCTOR_P
+ (pack_ts_type_common_value_fields): Add TYPE_FINAL_P.
+
+2013-08-29 Teresa Johnson <tejohnson@google.com>
+
+ * dumpfile.c (dump_loc): Output column number.
+ * dumpfile.h (OPTGROUP_OTHER): Add and enable under OPTGROUP_ALL.
+ * doc/invoke.texi: Document optall -fopt-info flag.
+ * profile.c (read_profile_edge_counts): Use new dump framework.
+ (compute_branch_probabilities): Ditto.
+ * passes.c (pass_manager::register_one_dump_file): Use OPTGROUP_OTHER
+ when pass not in any opt group.
+ * pass_manager.h (pass_manager::get_pass_profile): New method.
+ * value-prof.c (check_counter): Use new dump framework.
+ (check_ic_target): Ditto.
+ * coverage.c (get_coverage_counts): Ditto.
+ (coverage_init): Setup new dump framework.
+
+ * testsuite/gcc.dg/pr40209.c: Use -fopt-info.
+ * testsuite/gcc.dg/pr26570.c: Ditto.
+ * testsuite/gcc.dg/pr32773.c: Ditto.
+ * testsuite/g++.dg/tree-ssa/dom-invalid.C: Ditto.
+ * testsuite/gcc.dg/inline-dump.c: New test.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58246
+ * tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Properly
+ handle the dominance check inside a basic-block.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57287
+ * tree-ssa-copy.c (may_propagate_copy): Allow propagating
+ of default defs that appear in abnormal PHI nodes.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57685
+ * tree-vrp.c (register_edge_assert_for_1): Recurse only for
+ single-use operands to avoid exponential complexity.
+
+2013-08-28 Dehao Chen <dehao@google.com>
+
+ * ipa-inline.c (edge_badness): Fix integer underflow.
+
+2013-08-28 Uros Bizjak <ubizjak@gmail.com>
+
+ * gtm-builtins.def (_ITM_free): Declare leaf.
+
+2013-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58067
+ * config/i386/i386.md (*tls_global_dynamic_64_largepic): New insn.
+ (*tls_local_dynamic_base_64_largepic): Likewise.
+ (tls_global_dynamic_64_<mode>, tls_local_dynamic_base_64_<mode>):
+ Remove predicate from call operand.
+ * config/i386/i386.c (ix86_tls_get_addr): For -mcmodel=large -fpic
+ return sum of pic_offset_table_rtx and UNSPEC_PLTOFF of the symbol.
+
+2013-08-28 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadedge.c (thread_around_empty_block): Remove
+ checks for the number of predecessors and successors allowed.
+ * tree-ssa-threadupdate.c (mark_threaded_blocks): Ignore requests
+ which require copying a joiner block if there is a request which
+ is a subpath that requires no joiner block copying.
+
+2013-08-28 Jan Hubicka <jh@suse.cz>
+
+ * lto-streamer-out.c (DFS_write_tree_body): Drop
+ BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX and BINFO_VPTR_INDEX.
+ (hash_tree): Do not hash DECL_DEFER_OUTPUT, BINFO_INHERITANCE_CHAIN,
+ BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX, DECL_IN_TEXT_SECTION.
+ * tree-streamer-in.c (unpack_ts_decl_common_value_fields):
+ Do not read DECL_ERROR_ISSUED.
+ (unpack_ts_decl_with_vis_value_fields): Do not read
+ DECL_DEFER_OUTPUT.
+ (lto_input_ts_binfo_tree_pointers): Do not read
+ BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX
+ * tree-streamer-out.c (pack_ts_decl_common_value_fields): Do not
+ write DECL_ERROR_ISSUED..
+ (pack_ts_decl_with_vis_value_fields): Do not write
+ DECL_DEFER_OUTPUT.
+ (write_ts_binfo_tree_pointers): Do not read BINFO_INHERITANCE_CHAIN,
+ BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX.
+ * print-tree.c (print_node): Do not print DECL_ERROR_ISSUED.
+ * tree.h (tree_decl_common): Update comment.
+ (DECL_ERROR_ISSUED): Remove.
+
+2013-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/58257
+ * omp-low.c (copy_var_decl): Copy over TREE_NO_WARNING flag.
+
+2013-08-28 Jan Hubicka <jh@suse.cz>
+
+ * builtins.def (free): Declare leaf.
+
+2013-08-27 David Malcolm <dmalcolm@redhat.com>
+
+ * gdbhooks.py: New.
+ * configure.ac (gdbinit.in): Add import of gcc/gdbhooks.py.
+ * configure: Regenerate.
+
+2013-08-27 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-prop.h (ipa_pass_through_data): New field type_preserved.
+ (ipa_ancestor_jf_data): Likewise.
+ (ipa_get_jf_pass_through_agg_preserved): Fix comment typo.
+ (ipa_get_jf_pass_through_type_preserved): New function.
+ (ipa_get_jf_ancestor_agg_preserved): Fix comment typo.
+ (ipa_get_jf_ancestor_type_preserved): New function.
+ * ipa-cp.c (ipa_get_jf_pass_through_result): Honor type_preserved flag.
+ (ipa_get_jf_ancestor_result): Likewise.
+ (propagate_vals_accross_pass_through): Use
+ ipa_get_jf_pass_through_result to do all the value mappings.
+ * ipa-prop.c (ipa_print_node_jump_functions_for_edge): Dump the
+ type_preserved flag.
+ (ipa_set_jf_cst_copy): New function.
+ (ipa_set_jf_simple_pass_through): Set the type_preserved flag.
+ (ipa_set_jf_arith_pass_through): Likewise.
+ (ipa_set_ancestor_jf): Likewise.
+ (compute_complex_assign_jump_func): Set type_preserved instead of
+ punting.
+ (ipa_compute_jump_functions_for_edge): Likewise.
+ (combine_known_type_and_ancestor_jfs): Honor type_preserved.
+ (update_jump_functions_after_inlining): Update type_preserved.
+ Explicitely create jump functions when combining one with pass_through.
+ (ipa_write_jump_function): Stream the type_preserved flags.
+ (ipa_read_jump_function): Likewise.
+
+2013-08-27 Jakub Jelinek <jakub@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in (omp-low.o): Depend on $(TARGET_H).
+ * cfgloop.h (struct loop): Add safelen, force_vect, simduid.
+ * function.h (struct function): Add has_force_vect_loops and
+ has_simduid_loops.
+ * gimple-pretty-print.c (dump_gimple_omp_for): Handle GF_OMP_FOR_KIND*.
+ * gimple.c (gimple_build_omp_critical): Add KIND argument and
+ handle it.
+ * gimple.def: Update CLAUSES comments.
+ * gimple.h (enum gf_mask): Add GF_OMP_FOR_KIND_{FOR,SIMD}.
+ (gimple_build_omp_for): Add argument to prototype.
+ (gimple_omp_for_kind): New.
+ (gimple_omp_for_set_kind): New.
+ * gimplify.c (enum gimplify_omp_var_data): Add GOVD_LINEAR to
+ GOVD_DATA_SHARE_CLASS.
+ (enum omp_region_type): Add ORT_SIMD.
+ (gimple_add_tmp_var): Handle ORT_SIMD.
+ (gimplify_var_or_parm_decl): Same.
+ (is_gimple_stmt): Same.
+ (omp_firstprivatize_variable): Same.
+ (omp_add_variable): Only use splay_tree_insert if lookup failed.
+ (omp_notice_variable): Handle ORT_SIMD.
+ (omp_is_private): Add SIMD argument and handle it as well as ORT_SIMD.
+ (omp_check_private): Handle ORT_SIMD.
+ (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_LINEAR and
+ OMP_CLAUSE_SAFELEN.
+ (gimplify_adjust_omp_clauses_1): Handle GOVD_LINEAR.
+ Handle OMP_CLAUSE_LASTPRIVATE.
+ (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_LINEAR and
+ OMP_CLAUSE_SAFELEN.
+ (gimplify_omp_for): Handle OMP_SIMD and OMP_CLAUSE_LINEAR.
+ (gimplify_expr): Handle OMP_SIMD.
+ * internal-fn.c (expand_GOMP_SIMD_LANE): New.
+ (expand_GOMP_SIMD_VF): New.
+ (expand_GOMP_SIMD_LAST_LANE): New.
+ * internal-fn.def (GOMP_SIMD_LANE): New.
+ (GOMP_SIMD_VF): New.
+ (GOMP_SIMD_LAST_LANE): New.
+ * omp-low.c: Include target.h.
+ (extract_omp_for_data): Handle OMP_SIMD, OMP_CLAUSE_LINEAR,
+ OMP_CLAUSE_SAFELEN.
+ (check_omp_nesting_restrictions): Same.
+ (omp_max_vf): New.
+ (lower_rec_simd_input_clauses): New.
+ (lower_rec_input_clauses): Handle OMP_SIMD, GF_OMP_FOR_KIND_SIMD,
+ OMP_CLAUSE_LINEAR.
+ (lower_lastprivate_clauses): Handle OMP_CLAUSE_LINEAR,
+ GF_OMP_FOR_KIND_SIMD, OMP_SIMD.
+ (expand_omp_build_assign): New.
+ (expand_omp_for_init_counts): New.
+ (expand_omp_for_init_vars): New.
+ (extract_omp_for_update_vars): New.
+ (expand_omp_for_generic): Use expand_omp_for_{init,update}_vars
+ and rewrite accordingly.
+ (expand_omp_simd): New.
+ (expand_omp_for): Use expand_omp_simd.
+ (lower_omp_for_lastprivate): Unshare vinit when appropriate.
+ (lower_omp_for): Do not lower the body.
+ * tree-data-ref (get_references_in_stmt): Allow IFN_GOMP_SIMD_LANE
+ in their own loops.
+ * tree-flow.h (find_omp_clause): Remove prototype.
+ * tree-if-conv.c (main_tree_if_conversion): Run if doing if conversion,
+ forcing vectorization of the loop, or if flag_tree_vectorize.
+ (gate_tree_if_conversion): Similarly.
+ * tree-inline.c (remap_gimple_stmt): Pass for kind argument to
+ gimple_build_omp_for.
+ (copy_cfg_body): set has_force_vect_loops and has_simduid_loops.
+ * tree-parloops (create_parallel_loop): Pass kind argument to
+ gimple_build_omp_for.
+ * tree-pretty-print.c (dump_omp_clause): Add cases for
+ OMP_CLAUSE_UNIFORM, OMP_CLAUSE_LINEAR, OMP_CLAUSE_SAFELEN,
+ OMP_CLAUSE__SIMDUID_.
+ (dump_generic_node): Handle OMP_SIMD.
+ * tree-ssa-ccp.c (likely_value): Handle IFN_GOMP_SIMD*.
+ * tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely_1): Do not
+ unroll OMP_SIMD loops here.
+ * tree-ssa-loop.c (gate_tree_vectorize): Run if has_force_vect_loops.
+ * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Handle
+ loop->safelen.
+ (vect_analyze_data_refs): Handle simd loops.
+ * tree-vect-loop.c (vectorizable_live_operation): Handle
+ IFN_GOMP_SIMD*.
+ * tree-vect-stmts.c (vectorizable_call): Handle IFN_GOMP_SIMD_LANE.
+ (vectorizable_store): Handle STMT_VINFO_SIMD_LANE_ACCESS_P.
+ (vectorizable_load): Same.
+ * tree-vectorizer.c: Include hash-table.h and tree-ssa-propagate.h.
+ (struct simduid_to_vf): New.
+ (simduid_to_vf::hash): New.
+ (simduid_to-vf::equal): New.
+ (struct simd_array_to_simduid): New.
+ (simd_array_to_simduid::hash): New.
+ (simd_array_to_simduid::equal): New.
+ (adjust_simduid_builtins): New.
+ (struct note_simd_array_uses_struct): New.
+ (note_simd_array_uses_cb): New.
+ (note_simd_array_uses): New.
+ (vectorize_loops): Handle simd hints and adjust simd builtins
+ accordingly.
+ * tree-vectorizer.h (struct _stmt_vec_info): Add
+ simd_lane_access_p field.
+ (STMT_VINFO_SIMD_LANE_ACCESS_P): New macro.
+ * tree.c (omp_clause_num_ops): Add entries for OMP_CLAUSE_LINEAR,
+ OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_, OMP_CLAUSE_UNIFORM.
+ (omp_clause_code_name): Same.
+ (walk_tree_1): Handle OMP_CLAUSE_UNIFORM, OMP_CLAUSE_SAFELEN,
+ OMP_CLAUSE__SIMDUID_, OMP_CLAUSE_LINEAR.
+ * tree.def (OMP_SIMD): New entry.
+ * tree.h (enum omp_clause_code): Add entries for OMP_CLAUSE_LINEAR,
+ OMP_CLAUSE_UNIFORM, OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_.
+ (OMP_CLAUSE_DECL): Adjust range for new clauses.
+ (OMP_CLAUSE_LINEAR_NO_COPYIN): New.
+ (OMP_CLAUSE_LINEAR_NO_COPYOUT): New.
+ (OMP_CLAUSE_LINEAR_STEP): New.
+ (OMP_CLAUSE_SAFELEN_EXPR): New.
+ (OMP_CLAUSE__SIMDUID__DECL): New.
+ (find_omp_clause): New prototype.
+
+2013-08-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Update
+ Haswell processor detection.
+
+2013-08-27 Christian Widmer <shadow@umbrox.de>
+
+ PR target/57927
+ * config/i386/driver-i386.c (host_detect_local_cpu): Add detection
+ of Ivy Bridge and Haswell processors. Assume core-avx2 for unknown
+ AVX2 capable processors.
+
+2013-08-27 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/arm_neon.h: Replace all inline asm implementations
+ of vget_low_* with implementations in terms of other intrinsics.
+
2013-08-27 Marc Glisse <marc.glisse@inria.fr>
PR middle-end/57219
@@ -61,7 +391,8 @@
2013-08-26 Jan Hubicka <jh@suse.cz>
- * gimple-fold.c (gimple_get_virt_method_for_binfo): Use ctor_for_folding.
+ * gimple-fold.c (gimple_get_virt_method_for_binfo): Use
+ ctor_for_folding.
2013-08-26 Jan Hubicka <jh@suse.cz>
@@ -90,8 +421,8 @@
2013-08-26 Jan Hubicka <jh@suse.cz>
- * cgraph.c (cgraph_speculative_call_info): Fix parameter order and formating;
- add sanity check.
+ * cgraph.c (cgraph_speculative_call_info): Fix parameter order and
+ formating; add sanity check.
(cgraph_resolve_speculation): Add FIXME about scaling profiles.
(cgraph_redirect_edge_call_stmt_to_callee): Fix ICE in debug dump.
* ipa-inline.c (heap_edge_removal_hook): Reset node growth cache.
@@ -470,7 +801,7 @@
Revert:
2013-08-20 Alexey Makhalov <makhaloff@gmail.com>
- * dce.c (fini_dce): Call df_analyze again just in case
+ * dce.c (fini_dce): Call df_analyze again just in case
delete_unmarked_insns removed anything.
2013-08-21 Joern Rennecke <joern.rennecke@embecosm.com>
@@ -596,7 +927,7 @@
* config/i386/linux-common.h: Likewise.
* config/mips/linux-common.h: Likewise.
-2013-08-20 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
+2013-08-20 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
* tree-ssa-ccp.c (get_default_value): Remove redundant condition
checks.
@@ -656,7 +987,7 @@
* config/rs6000/rs6000.c (rs6000_emit_prologue): Correct ool_adjust.
(rs6000_emit_epilogue): Likewise.
-2013-08-19 Dehao Chen (dehao@google.com)
+2013-08-19 Dehao Chen <dehao@google.com>
* value-prof.c (gimple_ic): Fix the bug of adding EH edge.
@@ -1331,7 +1662,7 @@
* config/i386/i386.c (ix86_option_override_internal):
Parsing -mtune-ctrl= option and set tune features.
-2013-08-07 Oleg Endo <olegendo@gcc.gnu.org>
+2013-08-07 Oleg Endo <olegendo@gcc.gnu.org>
PR other/12081
* config/rs6000/rs6000.c (gen_2arg_fn_t): Remove typedef.
@@ -1456,7 +1787,7 @@
* gimple-ssa-strength-reduction.c (replace_ref): Make sure built
MEM_REF has proper alignment information.
-2013-08-05 Oleg Endo <olegendo@gcc.gnu.org>
+2013-08-05 Oleg Endo <olegendo@gcc.gnu.org>
PR other/12081
* recog.h (rtx (*insn_gen_fn) (rtx, ...)): Replace typedef with new
@@ -3633,7 +3964,7 @@
shift_add/shift_sub0/shift_sub1 RTXs.
2013-07-24 Bill Schmidt <wschmidt@linux.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/altivec.md (altivec_vpkpx): Handle little endian.
(altivec_vpks<VI_char>ss): Likewise.
@@ -3663,7 +3994,7 @@
don't set a return register to need a non-exit mode.
2013-07-24 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/vector.md (vec_realign_load_<mode>): Reorder input
operands to vperm for little endian.
@@ -3671,7 +4002,7 @@
of lvsl to create the control mask for a vperm for little endian.
2013-07-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/rs6000.c (altivec_expand_vec_perm_const): Reverse
two operands for little-endian.
@@ -3682,7 +4013,7 @@
(TARGET_CASE_VALUES_THRESHOLD): Define.
2013-07-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/rs6000.c (altivec_expand_vec_perm_const): Correct
selection of field for vector splat in little endian mode.
@@ -3777,12 +4108,12 @@
(eqv<mode>3_internal2): Likewise.
(one_cmpl1<mode>3_internal): Likewise.
-2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
+2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/microblaze.c (microblaze_expand_prologue):
Rename flag_stack_usage to flag_stack_usage_info.
-2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
+2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/sync.md: New file.
* config/microblaze/microblaze.md: Include sync.md
@@ -3919,7 +4250,7 @@
* config/avr/avr.md: Explain asm print modifier 'r' for REG.
2013-07-22 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/rs6000.c (rs6000_expand_vector_init): Fix
endianness when selecting field to splat.
@@ -4202,12 +4533,12 @@
(avr_out_round): New function.
(avr_adjust_insn_length): Handle ADJUST_LEN_ROUND.
-2013-07-18 David Holsgrove <david.holsgrove@xilinx.com>
+2013-07-18 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/microblaze.c (microblaze_expand_prologue):
Add check for flag_stack_usage to handle -fstack-usage support
-2013-07-18 Pat Haugen <pthaugen@us.ibm.com>
+2013-07-18 Pat Haugen <pthaugen@us.ibm.com>
* config/rs6000/rs6000.c (rs6000_option_override_internal): Adjust flag
interaction for new Power8 flags and VSX.
@@ -5372,7 +5703,7 @@
* config/i386/i386.c (enum ix86_builtins, bdesc_args): Remove
IX86_BUILTIN_CMPNGTSS and IX86_BUILTIN_CMPNGESS.
-2013-06-27 Catherine Moore <clm@codesourcery.com>
+2013-06-27 Catherine Moore <clm@codesourcery.com>
* config/mips/mips-tables.opt: Regenerate.
* config/mips/mips-cpus.def: Add m14ke and m14kec.
@@ -5485,8 +5816,8 @@
(TARGET_CAN_SPLIT_STACK, TARGET_THREAD_SPLIT_STACK_OFFSET): Undefine.
2013-06-26 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/power8.md: New.
* config/rs6000/rs6000-cpus.def (RS6000_CPU table): Adjust processor
@@ -5615,7 +5946,7 @@
* common/config/i386/i386-common.c (ix86_handle_option): For OPT_mlzcnt
add missing return true.
-2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
PR target/52483
* config/sh/predicates.md (general_extend_operand): Invoke
@@ -5672,7 +6003,7 @@
* doc/extend.texi: Use __atomic_store_n instead of
__atomic_store in HLE example.
-2013-06-22 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-22 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/sh.c: Remove <cstdlib> workaround.
@@ -5695,7 +6026,7 @@
(get_binfo_at_offset): Use it.
* tree.h (types_same_for_odr): Declare.
-2013-06-20 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-20 Oleg Endo <olegendo@gcc.gnu.org>
Jason Merrill <jason@redhat.com>
* system.h: Include <cstdlib> as well as <stdlib.h>.
@@ -5710,7 +6041,7 @@
* lto-cgraph.c (input_symtab): Do not set cgraph state.
-2013-06-20 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-06-20 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
@@ -6188,7 +6519,7 @@
Likewise. Remove default with_tune setting. Move default float
setting to its own block. Handle with_llsc in the same block as above.
-2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
@@ -6224,7 +6555,7 @@
rs6000_output_move_128bit to handle emitting quad memory
operations. Set attribute length to 8 bytes.
-2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
+2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
* config/aarch64/aarch64-simd.md (aarch64_<su>mlal_lo<mode>):
New pattern.
@@ -6293,8 +6624,8 @@
* config/rs6000/spe.md (spe_abstf2_cmp, spe_abstf2_tst): Likewise.
2013-06-12 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/rs6000.c (emit_load_locked): Add support for
power8 byte, half-word, and quad-word atomic instructions.
@@ -6381,7 +6712,7 @@
* lto-symtab.c (lto_symtab_merge_symbols): Likewise.
* cgraph.h (cgraph_state): Add CGRAPH_LTO_STREAMING.
-2013-06-12 Roland Stigge <stigge@antcom.de>
+2013-06-12 Roland Stigge <stigge@antcom.de>
PR target/57578
* config/rs6000/t-linux (MULTIARCH_DIRNAME): Fix SPE version detection.
@@ -6521,8 +6852,8 @@
for hash so that hash table traversal order is deterministic.
2013-06-10 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/vector.md (GPR move splitter): Do not split moves
of vectors in GPRS if they are direct moves or quad word load or
@@ -6750,8 +7081,8 @@
TARGET_VALID_POINTER_MODE.
2013-06-06 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions):
Document new power8 builtins.
@@ -7502,7 +7833,7 @@
* config/aarch64/aarch64.md (insv<mode>): New define_expand.
(*insv_reg<mode>): New define_insn.
-2013-05-30 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-30 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57439
* postreload.c (move2add_valid_value_p): Check that we have
@@ -7595,8 +7926,8 @@
functions are not yet marked as defined.
2013-05-29 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/vector.md (VEC_I): Add support for new power8 V2DI
instructions.
@@ -7912,7 +8243,7 @@
(MULTILIB_DIRNAMES): Ditto.
(MULTILIB_EXCEPTIONS): Add new exceptions.
-2012-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2012-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_symbol_type): Define
@@ -7925,7 +8256,7 @@
Permit SYMBOL_TINY_ABSOLUTE.
* config/aarch64/predicates.md (aarch64_mov_operand): Permit CONST.
-2013-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2013-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64.c (aarch64_classify_symbol): Remove comment.
@@ -7975,7 +8306,7 @@
* builtin-types.def: Define BT_FN_INT_PTR_PTR_PTR.
* cilkplus.def: New file.
-2013-05-28 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-28 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57439
* postreload.c (move2add_use_add2_insn): Use gen_lowpart_common.
@@ -8059,7 +8390,7 @@
(set_ssa_val_to): Compare addresses using
get_addr_base_and_unit_offset.
-2013-05-27 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-27 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/56833
* postreload.c (move2add_record_mode): New function.
@@ -8225,14 +8556,14 @@
PR debug/57351
* config/arm/arm.c (arm_dwarf_register_span): Do not use dbx number.
-2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64.md (*movdi_aarch64): Replace Usa with S.
* config/aarch64/constraints.md (Usa): Remove.
* doc/md.texi (AArch64 Usa): Remove.
-2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_mov_operand_p): Define.
@@ -8240,7 +8571,7 @@
* config/aarch64/predicates.md (aarch64_const_address): Remove.
(aarch64_mov_operand): Use aarch64_mov_operand_p.
-2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
+2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
* config/aarch64/aarch64-simd.md (clzv4si2): Support for CLZ
instruction (AdvSIMD).
@@ -8295,8 +8626,8 @@
(exec_threshold): Ditto.
2013-05-22 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions): Add
documentation for the power8 crypto builtins.
@@ -8348,8 +8679,8 @@
instructions.
2013-05-22 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* doc/invoke.texi (Option Summary): Add power8 options.
(RS/6000 and PowerPC Options): Likewise.
@@ -9109,7 +9440,7 @@
* config/arm/arm.h (EPILOGUE_USES): Only return true
for LR_REGNUM after epilogue_completed.
-2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
* config/avr/avr.c (avr_encode_section_info): Bail out if the type
is error_mark_node.
@@ -9992,7 +10323,7 @@
*vec_concatv2si_sse2 and vec_concatv2si_sse.
(vec_concatv2di): Merge with *vec_concatv2di_rex64.
-2013-05-03 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-03 Joern Rennecke <joern.rennecke@embecosm.com>
PR tree-optimization/57027
* tree-ssa-math-opts.c (convert_mult_to_fma): When checking
@@ -11359,7 +11690,7 @@
(scev_analysis): Likewise.
2013-04-02 Catherine Moore <clm@codesourcery.com>
- Chao-ying Fu <fu@mips.com>
+ Chao-ying Fu <fu@mips.com>
* config/mips/micromips.md (jraddiusp): New pattern.
* config/mips/mips.c (mips_expand_epilogue): Use the JRADDIUSP
@@ -12274,7 +12605,7 @@
(vect_get_constant_vectors): Handle mixed vect_external_def,
vect_constant_def types.
-2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
PR tree-optimization/55524
* tree-ssa-math-opts.c
@@ -12282,7 +12613,7 @@
when we don't have an fms operation, but fnma, and it looks
likely that we'll be able to use the latter.
-2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
+2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
* cif-code.def (OVERWRITABLE): Correct the comment for overwritable
function.
@@ -12760,7 +13091,7 @@
* basic-block.h (gcov_working_set_t): Moved to gcov-io.h.
* gcov-dump.c (dump_working_sets): New function.
-2013-04-03 Kenneth Zadeck <zadeck@naturalbridge.com>
+2013-04-03 Kenneth Zadeck <zadeck@naturalbridge.com>
* hwint.c (sext_hwi, zext_hwi): New functions.
* hwint.h (HOST_BITS_PER_HALF_WIDE_INT, HOST_HALF_WIDE_INT,
@@ -14288,7 +14619,7 @@
* params.def (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS): New parameter.
* ipa-cp.c (hint_time_bonus): Add abonus for known array indices.
-2013-03-20 Pat Haugen <pthaugen@us.ibm.com>
+2013-03-20 Pat Haugen <pthaugen@us.ibm.com>
* config/rs6000/predicates.md (indexed_address, update_address_mem
update_indexed_address_mem): New predicates.
@@ -14595,10 +14926,10 @@
2013-03-20 Catherine Moore <clm@codesourcery.com>
Maciej W. Rozycki <macro@codesourcery.com>
Tom de Vries <tom@codesourcery.com>
- Nathan Sidwell <nathan@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
Iain Sandoe <iain@codesourcery.com>
Nathan Froyd <froydnj@codesourcery.com>
- Chao-ying Fu <fu@mips.com>
+ Chao-ying Fu <fu@mips.com>
* doc/extend.texi: (micromips, nomicromips, nocompression):
Document new function attributes.
@@ -14730,7 +15061,7 @@
remap_gimple_op_r.
2013-03-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
- Steven Bosscher <steven@gcc.gnu.org>
+ Steven Bosscher <steven@gcc.gnu.org>
PR rtl-optimization/56605
* loop-iv.c (implies_p): Handle equal RTXs and subregs.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 6733c07f773..90c5253341a 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20130827
+20130830
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index b7f1a68ca67..7396313e1bb 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2573,7 +2573,7 @@ omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_CORE_H) \
$(TREE_FLOW_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \
$(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \
- $(CFGLOOP_H) tree-iterator.h gt-omp-low.h
+ $(CFGLOOP_H) tree-iterator.h $(TARGET_H) gt-omp-low.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(HASH_TABLE_H) $(TREE_H) $(TREE_PRETTY_PRINT_H)
omega.o : omega.c $(OMEGA_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
@@ -2980,7 +2980,7 @@ ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TREE_PASS_H) \
$(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H) \
$(EXCEPT_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(TARGET_H) \
- $(IPA_UTILS_H)
+ $(IPA_UTILS_H) sreal.h
ipa-inline-analysis.o : ipa-inline-analysis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(PARAMS_H) $(TREE_PASS_H) $(CFGLOOP_H) \
diff --git a/gcc/builtins.def b/gcc/builtins.def
index e3253602c42..8ccf3ae3578 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -695,7 +695,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_
DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL)
/* [trans-mem]: Adjust BUILT_IN_TM_FREE if BUILT_IN_FREE is changed. */
-DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 0f247996630..cd2f527bb47 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -168,6 +168,20 @@ struct GTY ((chain_next ("%h.next"))) loop {
describes what is the state of the estimation. */
enum loop_estimation estimate_state;
+ /* If > 0, an integer, where the user asserted that for any
+ I in [ 0, nb_iterations ) and for any J in
+ [ I, min ( I + safelen, nb_iterations ) ), the Ith and Jth iterations
+ of the loop can be safely evaluated concurrently. */
+ int safelen;
+
+ /* True if we should try harder to vectorize this loop. */
+ bool force_vect;
+
+ /* For SIMD loops, this is a unique identifier of the loop, referenced
+ by IFN_GOMP_SIMD_VF, IFN_GOMP_SIMD_LANE and IFN_GOMP_SIMD_LAST_LANE
+ builtins. */
+ tree simduid;
+
/* Upper bound on number of iterations of a loop. */
struct nb_iter_bound *bounds;
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 063c5245fef..feb17bb0dd9 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1663,6 +1663,8 @@ cgraph_release_function_body (struct cgraph_node *node)
if (!node->used_as_abstract_origin && DECL_INITIAL (node->symbol.decl))
DECL_INITIAL (node->symbol.decl) = error_mark_node;
release_function_body (node->symbol.decl);
+ if (node->symbol.lto_file_data)
+ lto_free_function_in_decl_state_for_node ((symtab_node) node);
}
/* Remove the node from cgraph. */
@@ -3107,10 +3109,11 @@ cgraph_get_body (struct cgraph_node *node)
gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
- lto_input_function_body (file_data, decl, data);
+ lto_input_function_body (file_data, node->symbol.decl, data);
lto_stats.num_function_bodies++;
lto_free_section_data (file_data, LTO_section_function_body, name,
data, len);
+ lto_free_function_in_decl_state_for_node ((symtab_node) node);
return true;
}
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index ae26a026d64..54b97b91c78 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -252,7 +252,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
return new_node;
}
-/* Create a new name for clone of DECL, add SUFFIX. Returns an identifier. */
+/* Return a new assembler name for a clone of DECL with SUFFIX. */
static GTY(()) unsigned int clone_fn_id_num;
@@ -293,8 +293,9 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
tree old_decl = old_node->symbol.decl;
struct cgraph_node *new_node = NULL;
tree new_decl;
- size_t i;
+ size_t len, i;
struct ipa_replace_map *map;
+ char *name;
if (!in_lto_p)
gcc_checking_assert (tree_versionable_function_p (old_decl));
@@ -318,8 +319,13 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
sometimes storing only clone decl instead of original. */
/* Generate a new name for the new version. */
- DECL_NAME (new_decl) = clone_function_name (old_decl, suffix);
- SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
+ len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
+ name = XALLOCAVEC (char, len + strlen (suffix) + 2);
+ memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
+ strcpy (name + len + 1, suffix);
+ name[len] = '.';
+ DECL_NAME (new_decl) = get_identifier (name);
+ SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name (old_decl, suffix));
SET_DECL_RTL (new_decl, NULL);
new_node = cgraph_clone_node (old_node, new_decl, old_node->count,
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 4a480fb3da7..74a5de9df90 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -3865,6 +3865,85 @@ vreinterpretq_u32_p16 (poly16x8_t __a)
return (uint32x4_t) __builtin_aarch64_reinterpretv4siv8hi ((int16x8_t) __a);
}
+#define __GET_LOW(__TYPE) \
+ uint64x2_t tmp = vreinterpretq_u64_##__TYPE (__a); \
+ uint64_t lo = vgetq_lane_u64 (tmp, 0); \
+ return vreinterpret_##__TYPE##_u64 (lo);
+
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vget_low_f32 (float32x4_t __a)
+{
+ __GET_LOW (f32);
+}
+
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vget_low_f64 (float64x2_t __a)
+{
+ return vgetq_lane_f64 (__a, 0);
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vget_low_p8 (poly8x16_t __a)
+{
+ __GET_LOW (p8);
+}
+
+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
+vget_low_p16 (poly16x8_t __a)
+{
+ __GET_LOW (p16);
+}
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vget_low_s8 (int8x16_t __a)
+{
+ __GET_LOW (s8);
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vget_low_s16 (int16x8_t __a)
+{
+ __GET_LOW (s16);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vget_low_s32 (int32x4_t __a)
+{
+ __GET_LOW (s32);
+}
+
+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
+vget_low_s64 (int64x2_t __a)
+{
+ return vgetq_lane_s64 (__a, 0);
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vget_low_u8 (uint8x16_t __a)
+{
+ __GET_LOW (u8);
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vget_low_u16 (uint16x8_t __a)
+{
+ __GET_LOW (u16);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vget_low_u32 (uint32x4_t __a)
+{
+ __GET_LOW (u32);
+}
+
+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
+vget_low_u64 (uint64x2_t __a)
+{
+ return vgetq_lane_u64 (__a, 0);
+}
+
+#undef __GET_LOW
+
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
vcombine_s8 (int8x8_t __a, int8x8_t __b)
{
@@ -6784,138 +6863,6 @@ vget_high_u64 (uint64x2_t a)
return result;
}
-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
-vget_low_f32 (float32x4_t a)
-{
- float32x2_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
-vget_low_f64 (float64x2_t a)
-{
- float64x1_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vget_low_p8 (poly8x16_t a)
-{
- poly8x8_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
-vget_low_p16 (poly16x8_t a)
-{
- poly16x4_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vget_low_s8 (int8x16_t a)
-{
- int8x8_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
-vget_low_s16 (int16x8_t a)
-{
- int16x4_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
-vget_low_s32 (int32x4_t a)
-{
- int32x2_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
-vget_low_s64 (int64x2_t a)
-{
- int64x1_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vget_low_u8 (uint8x16_t a)
-{
- uint8x8_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-vget_low_u16 (uint16x8_t a)
-{
- uint16x4_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
-vget_low_u32 (uint32x4_t a)
-{
- uint32x2_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
-vget_low_u64 (uint64x2_t a)
-{
- uint64x1_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vhsub_s8 (int8x8_t a, int8x8_t b)
{
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index ee7ed23c8bb..4cb9907b5ed 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -644,13 +644,18 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* Atom. */
cpu = "atom";
break;
+ case 0x0f:
+ /* Merom. */
+ case 0x17:
+ case 0x1d:
+ /* Penryn. */
+ cpu = "core2";
+ break;
case 0x1a:
case 0x1e:
case 0x1f:
case 0x2e:
/* Nehalem. */
- cpu = "corei7";
- break;
case 0x25:
case 0x2c:
case 0x2f:
@@ -662,20 +667,25 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* Sandy Bridge. */
cpu = "corei7-avx";
break;
- case 0x17:
- case 0x1d:
- /* Penryn. */
- cpu = "core2";
+ case 0x3a:
+ case 0x3e:
+ /* Ivy Bridge. */
+ cpu = "core-avx-i";
break;
- case 0x0f:
- /* Merom. */
- cpu = "core2";
+ case 0x3c:
+ case 0x45:
+ case 0x46:
+ /* Haswell. */
+ cpu = "core-avx2";
break;
default:
if (arch)
{
/* This is unknown family 0x6 CPU. */
- if (has_avx)
+ if (has_avx2)
+ /* Assume Haswell. */
+ cpu = "core-avx2";
+ else if (has_avx)
/* Assume Sandy Bridge. */
cpu = "corei7-avx";
else if (has_sse4_2)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d0818ad39ac..a8d70bc49b3 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -13048,6 +13048,14 @@ ix86_tls_get_addr (void)
ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
}
+ if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
+ {
+ rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
+ UNSPEC_PLTOFF);
+ return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ gen_rtx_CONST (Pmode, unspec));
+ }
+
return ix86_tls_symbol;
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 3d7533a12f1..3307b081aaa 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12397,11 +12397,33 @@
(set (attr "length")
(symbol_ref "TARGET_X32 ? 15 : 16"))])
+(define_insn "*tls_global_dynamic_64_largepic"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (call:DI
+ (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
+ (match_operand:DI 3 "immediate_operand" "i")))
+ (match_operand 4)))
+ (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
+ UNSPEC_TLS_GD)]
+ "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
+ && GET_CODE (operands[3]) == CONST
+ && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
+ && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
+{
+ output_asm_insn
+ ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
+ output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
+ output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
+ return "call\t{*%%rax|rax}";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "22")])
+
(define_expand "tls_global_dynamic_64_<mode>"
[(parallel
[(set (match_operand:P 0 "register_operand")
(call:P
- (mem:QI (match_operand 2 "constant_call_address_operand"))
+ (mem:QI (match_operand 2))
(const_int 0)))
(unspec:P [(match_operand 1 "tls_symbolic_operand")]
UNSPEC_TLS_GD)])]
@@ -12459,11 +12481,32 @@
[(set_attr "type" "multi")
(set_attr "length" "12")])
+(define_insn "*tls_local_dynamic_base_64_largepic"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (call:DI
+ (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "immediate_operand" "i")))
+ (match_operand 3)))
+ (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
+ "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
+ && GET_CODE (operands[2]) == CONST
+ && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
+ && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
+{
+ output_asm_insn
+ ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
+ output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
+ output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
+ return "call\t{*%%rax|rax}";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "22")])
+
(define_expand "tls_local_dynamic_base_64_<mode>"
[(parallel
[(set (match_operand:P 0 "register_operand")
(call:P
- (mem:QI (match_operand 1 "constant_call_address_operand"))
+ (mem:QI (match_operand 1))
(const_int 0)))
(unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
"TARGET_64BIT")
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index c23fdf95a8c..93b5de69365 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -1021,9 +1021,9 @@ rx_gen_move_template (rtx * operands, bool is_movu)
gcc_assert (! is_movu);
if (REG_P (src) && REG_P (dest) && (REGNO (dest) == REGNO (src) + 1))
- sprintf (out_template, "mov.L\t%H1, %H0 | mov.L\t%1, %0");
+ sprintf (out_template, "mov.L\t%%H1, %%H0 ! mov.L\t%%1, %%0");
else
- sprintf (out_template, "mov.L\t%1, %0 | mov.L\t%H1, %H0");
+ sprintf (out_template, "mov.L\t%%1, %%0 ! mov.L\t%%H1, %%H0");
}
else
sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
@@ -3270,7 +3270,7 @@ rx_ok_to_inline (tree caller, tree callee)
static bool
rx_enable_lra (void)
{
- return TARGET_ENABLE_LRA || 1;
+ return TARGET_ENABLE_LRA;
}
diff --git a/gcc/configure b/gcc/configure
index ec662f50233..c6bc3a69d84 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -27397,6 +27397,7 @@ if test "x$subdirs" != x; then
done
fi
echo "source ${srcdir}/gdbinit.in" >> .gdbinit
+echo "python import sys; sys.path.append('${srcdir}'); import gdbhooks" >> .gdbinit
gcc_tooldir='$(libsubdir)/$(libsubdir_to_prefix)$(target_noncanonical)'
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 62d3053e6e6..5d3e5ad5823 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -5181,6 +5181,7 @@ if test "x$subdirs" != x; then
done
fi
echo "source ${srcdir}/gdbinit.in" >> .gdbinit
+echo "python import sys; sys.path.append('${srcdir}'); import gdbhooks" >> .gdbinit
gcc_tooldir='$(libsubdir)/$(libsubdir_to_prefix)$(target_noncanonical)'
AC_SUBST(gcc_tooldir)
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 9b664cf1500..d662e8d0946 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -43,6 +43,9 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "hash-table.h"
#include "tree-iterator.h"
+#include "context.h"
+#include "pass_manager.h"
+#include "tree-pass.h"
#include "cgraph.h"
#include "dumpfile.h"
#include "diagnostic-core.h"
@@ -341,11 +344,13 @@ get_coverage_counts (unsigned counter, unsigned expected,
{
static int warned = 0;
- if (!warned++)
- inform (input_location, (flag_guess_branch_prob
- ? "file %s not found, execution counts estimated"
- : "file %s not found, execution counts assumed to be zero"),
- da_file_name);
+ if (!warned++ && dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ (flag_guess_branch_prob
+ ? "file %s not found, execution counts estimated"
+ : "file %s not found, execution counts assumed to "
+ "be zero"),
+ da_file_name);
return NULL;
}
@@ -369,21 +374,25 @@ get_coverage_counts (unsigned counter, unsigned expected,
warning_at (input_location, OPT_Wcoverage_mismatch,
"the control flow of function %qE does not match "
"its profile data (counter %qs)", id, ctr_names[counter]);
- if (warning_printed)
+ if (warning_printed && dump_enabled_p ())
{
- inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
- "the mismatch but performance may drop if the function is hot");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ "use -Wno-error=coverage-mismatch to tolerate "
+ "the mismatch but performance may drop if the "
+ "function is hot");
if (!seen_error ()
&& !warned++)
{
- inform (input_location, "coverage mismatch ignored");
- inform (input_location, flag_guess_branch_prob
- ? G_("execution counts estimated")
- : G_("execution counts assumed to be zero"));
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ "coverage mismatch ignored");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ flag_guess_branch_prob
+ ? G_("execution counts estimated")
+ : G_("execution counts assumed to be zero"));
if (!flag_guess_branch_prob)
- inform (input_location,
- "this can result in poorly optimized code");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ "this can result in poorly optimized code");
}
}
@@ -1125,6 +1134,11 @@ coverage_init (const char *filename)
int len = strlen (filename);
int prefix_len = 0;
+ /* Since coverage_init is invoked very early, before the pass
+ manager, we need to set up the dumping explicitly. This is
+ similar to the handling in finish_optimization_passes. */
+ dump_start (g->get_passes ()->get_pass_profile ()->static_pass_number, NULL);
+
if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
profile_data_prefix = getpwd ();
@@ -1167,6 +1181,8 @@ coverage_init (const char *filename)
gcov_write_unsigned (bbg_file_stamp);
}
}
+
+ dump_finish (g->get_passes ()->get_pass_profile ()->static_pass_number);
}
/* Performs file-level cleanup. Close notes file, generate coverage
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 98d007e5f20..2b2f45aab00 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,81 @@
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtbl_initializer): Make __cxa_deleted_virtual
+ ECF_NORETURN | ECF_LEAF
+ * cp-tree.h (build_library_fn_ptr, build_cp_library_fn_ptr,
+ push_library_fn, push_void_library_fn): Update prototype.
+ * decl.c (build_library_fn_1): Remove.
+ (push_cp_library_fn, build_cp_library_fn): Update to take ECF flags.
+ (cxx_init_decl_processing): Update; global_delete_fndecl is ECF_NOTROW;
+ __cxa_pure_virtual is ECF_NORETURN | ECF_NORETURN | ECF_LEAF.
+ (build_library_fn_1): Add ecf_flags argument; rename to ...
+ (build_library_fn): ... this one.
+ (build_cp_library_fn): Take ecf_flags; do not copy NOTHROW flag.
+ (build_library_fn_ptr): Take ecf_flags.
+ (build_cp_library_fn_ptr): Likewise.
+ (push_library_fn): Likewise.
+ (push_cp_library_fn): Likewise.
+ (push_void_library_fn): Likewise.
+ (push_throw_library_fn): All throws are ECF_NORETURN.
+ (__cxa_atexit, __cxa_thread_atexit): Add ECF_LEAF | ECF_NOTHROW attributes.
+ (expand_static_init): __cxa_guard_acquire, __cxa_guard_release,
+ __cxa_guard_abort are ECF_NOTHROW | ECF_LEAF.
+ * except.c (init_exception_processing): terminate is
+ ECF_NOTHROW | ECF_NORETURN | ECF_LEAF.
+ (declare_nothrow_library_fn): Add ecf_flags parameter.
+ (__cxa_get_exception_ptr): Is ECF_NOTHROW | ECF_PURE | ECF_LEAF |
+ ECF_TM_PURE.
+ (do_begin_catch): cxa_begin_catch and _ITM_cxa_begin_catch
+ are ECF_NOTHROW | ECF_LEAF.
+ (do_end_catch): __cxa_end_catch and _ITM_cxa_end_catch is
+ ECF_LEAF.
+ (do_allocate_exception): _cxa_allocate_exception
+ and _ITM_cxa_allocate_exception are ECF_NOTHROW | ECF_MALLOC
+ | ECF_LEAF
+ (do_free_exception): __cxa_free_exception is
+ ECF_NOTHROW | ECF_LEAF.
+ * rtti.c (build_dynamic_cast_1): __dynamic_cast
+ is ECF_LEAF | ECF_PURE | ECF_NOTHROW.
+
+2013-08-29 Adam Butcher <adam@jessamine.co.uk>
+
+ * error.c (dump_lambda_function): New function, dependent on ...
+ (dump_substitution): ... this new function, factored out of ...
+ (subst_to_string): ... here and ...
+ (dump_function_decl): ... here. Updated to early-out with call to
+ dump_lambda_function after determining template bindings.
+
+2013-08-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58255
+ * init.c (build_aggr_init): When init == void_type_node do not
+ set LOOKUP_ONLYCONVERTING.
+
+2013-08-27 Caroline Tice <cmtice@google.com>
+
+ * vtable-class-hierarchy.c: Remove unnecessary include statements.
+ (MAX_SET_SIZE): Remove unnecessary constant.
+ (register_construction_vtables): Make vtable_ptr_array parameter
+ into a vector; remove num_args parameter. Change array accesses to
+ vector accesses.
+ (register_other_binfo_vtables): Ditto.
+ (insert_call_to_register_set): Ditto.
+ (insert_call_to_register_pair): Ditto.
+ (output_set_info): Ditto. Also change warning calls to warning_at
+ calls, and fix format of warning messages.
+ (register_all_pairs): Change vtbl_ptr_array from an array into a
+ vector. Remove num_vtable_args (replace with calls to vector length).
+ Change array stores & accesses to vector functions. Change calls to
+ register_construction_vtables, register_other_binfo_vtables,
+ insert_call_to_register_set, insert_call_to_register_pair and
+ output_set_info to match their new signatures. Change warning to
+ warning_at and fix the format of the warning message.
+
+2013-08-27 Jakub Jelinek <jakub@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (CP_OMP_CLAUSE_INFO): Adjust range for new clauses.
+
2013-08-27 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (grokfndecl): Remove old bison hack.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 596b13d2695..3f77d22fcc9 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -8873,7 +8873,7 @@ build_vtbl_initializer (tree binfo,
if (!get_global_value_if_present (fn, &fn))
fn = push_library_fn (fn, (build_function_type_list
(void_type_node, NULL_TREE)),
- NULL_TREE);
+ NULL_TREE, ECF_NORETURN | ECF_LEAF);
if (!TARGET_VTABLE_USES_DESCRIPTORS)
init = fold_convert (vfunc_ptr_type_node,
build_fold_addr_expr (fn));
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 61fdf437b70..73f6a6ad43b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4020,7 +4020,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
See semantics.c for details. */
#define CP_OMP_CLAUSE_INFO(NODE) \
TREE_TYPE (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_PRIVATE, \
- OMP_CLAUSE_COPYPRIVATE))
+ OMP_CLAUSE_LINEAR))
/* Nonzero if this transaction expression's body contains statements. */
#define TRANSACTION_EXPR_IS_STMT(NODE) \
@@ -5170,10 +5170,10 @@ extern void check_goto (tree);
extern bool check_omp_return (void);
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
-extern tree build_library_fn_ptr (const char *, tree);
-extern tree build_cp_library_fn_ptr (const char *, tree);
-extern tree push_library_fn (tree, tree, tree);
-extern tree push_void_library_fn (tree, tree);
+extern tree build_library_fn_ptr (const char *, tree, int);
+extern tree build_cp_library_fn_ptr (const char *, tree, int);
+extern tree push_library_fn (tree, tree, tree, int);
+extern tree push_void_library_fn (tree, tree, int);
extern tree push_throw_library_fn (tree, tree);
extern void warn_misplaced_attr_for_class_type (source_location location,
tree class_type);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 4076a24cf6a..bead6e84183 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -75,7 +75,6 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
static int check_static_variable_definition (tree, tree);
static void record_unknown_type (tree, const char *);
static tree builtin_function_1 (tree, tree, bool);
-static tree build_library_fn_1 (tree, enum tree_code, tree);
static int member_function_or_else (tree, tree, enum overload_flags);
static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
int);
@@ -107,8 +106,8 @@ static tree cp_make_fname_decl (location_t, tree, int);
static void initialize_predefined_identifiers (void);
static tree check_special_function_return_type
(special_function_kind, tree, tree);
-static tree push_cp_library_fn (enum tree_code, tree);
-static tree build_cp_library_fn (tree, enum tree_code, tree);
+static tree push_cp_library_fn (enum tree_code, tree, int);
+static tree build_cp_library_fn (tree, enum tree_code, tree, int);
static void store_parm_decls (tree);
static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree);
@@ -3800,10 +3799,10 @@ cxx_init_decl_processing (void)
newtype = build_exception_variant (newtype, new_eh_spec);
deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
- push_cp_library_fn (NEW_EXPR, newtype);
- push_cp_library_fn (VEC_NEW_EXPR, newtype);
- global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
- push_cp_library_fn (VEC_DELETE_EXPR, deltype);
+ push_cp_library_fn (NEW_EXPR, newtype, 0);
+ push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
+ global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
nullptr_type_node = make_node (NULLPTR_TYPE);
TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
@@ -3816,7 +3815,8 @@ cxx_init_decl_processing (void)
}
abort_fndecl
- = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
+ = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype,
+ ECF_NORETURN | ECF_NOTHROW | ECF_LEAF);
/* Perform other language dependent initializations. */
init_class_processing ();
@@ -4007,7 +4007,8 @@ cxx_builtin_function_ext_scope (tree decl)
function. Not called directly. */
static tree
-build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
+build_library_fn (tree name, enum tree_code operator_code, tree type,
+ int ecf_flags)
{
tree fn = build_lang_decl (FUNCTION_DECL, name, type);
DECL_EXTERNAL (fn) = 1;
@@ -4019,28 +4020,17 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
external shared object. */
DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
DECL_VISIBILITY_SPECIFIED (fn) = 1;
- return fn;
-}
-
-/* Returns the _DECL for a library function with C linkage.
- We assume that such functions never throw; if this is incorrect,
- callers should unset TREE_NOTHROW. */
-
-static tree
-build_library_fn (tree name, tree type)
-{
- tree fn = build_library_fn_1 (name, ERROR_MARK, type);
- TREE_NOTHROW (fn) = 1;
+ set_call_expr_flags (fn, ecf_flags);
return fn;
}
/* Returns the _DECL for a library function with C++ linkage. */
static tree
-build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
+build_cp_library_fn (tree name, enum tree_code operator_code, tree type,
+ int ecf_flags)
{
- tree fn = build_library_fn_1 (name, operator_code, type);
- TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
+ tree fn = build_library_fn (name, operator_code, type, ecf_flags);
DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
SET_DECL_LANGUAGE (fn, lang_cplusplus);
return fn;
@@ -4050,18 +4040,19 @@ build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
IDENTIFIER_NODE. */
tree
-build_library_fn_ptr (const char* name, tree type)
+build_library_fn_ptr (const char* name, tree type, int ecf_flags)
{
- return build_library_fn (get_identifier (name), type);
+ return build_library_fn (get_identifier (name), ERROR_MARK, type, ecf_flags);
}
/* Like build_cp_library_fn, but takes a C string instead of an
IDENTIFIER_NODE. */
tree
-build_cp_library_fn_ptr (const char* name, tree type)
+build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags)
{
- return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
+ return build_cp_library_fn (get_identifier (name), ERROR_MARK, type,
+ ecf_flags);
}
/* Like build_library_fn, but also pushes the function so that we will
@@ -4069,14 +4060,14 @@ build_cp_library_fn_ptr (const char* name, tree type)
may throw exceptions listed in RAISES. */
tree
-push_library_fn (tree name, tree type, tree raises)
+push_library_fn (tree name, tree type, tree raises, int ecf_flags)
{
tree fn;
if (raises)
type = build_exception_variant (type, raises);
- fn = build_library_fn (name, type);
+ fn = build_library_fn (name, ERROR_MARK, type, ecf_flags);
pushdecl_top_level (fn);
return fn;
}
@@ -4085,11 +4076,12 @@ push_library_fn (tree name, tree type, tree raises)
will be found by normal lookup. */
static tree
-push_cp_library_fn (enum tree_code operator_code, tree type)
+push_cp_library_fn (enum tree_code operator_code, tree type,
+ int ecf_flags)
{
tree fn = build_cp_library_fn (ansi_opname (operator_code),
operator_code,
- type);
+ type, ecf_flags);
pushdecl (fn);
if (flag_tm)
apply_tm_attr (fn, get_identifier ("transaction_safe"));
@@ -4100,10 +4092,10 @@ push_cp_library_fn (enum tree_code operator_code, tree type)
a FUNCTION_TYPE. */
tree
-push_void_library_fn (tree name, tree parmtypes)
+push_void_library_fn (tree name, tree parmtypes, int ecf_flags)
{
tree type = build_function_type (void_type_node, parmtypes);
- return push_library_fn (name, type, NULL_TREE);
+ return push_library_fn (name, type, NULL_TREE, ecf_flags);
}
/* Like push_library_fn, but also note that this function throws
@@ -4112,9 +4104,7 @@ push_void_library_fn (tree name, tree parmtypes)
tree
push_throw_library_fn (tree name, tree type)
{
- tree fn = push_library_fn (name, type, NULL_TREE);
- TREE_THIS_VOLATILE (fn) = 1;
- TREE_NOTHROW (fn) = 0;
+ tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN | ECF_LEAF);
return fn;
}
@@ -6644,7 +6634,7 @@ get_atexit_node (void)
/* Now, build the function declaration. */
push_lang_context (lang_name_c);
- atexit_fndecl = build_library_fn_ptr (name, fn_type);
+ atexit_fndecl = build_library_fn_ptr (name, fn_type, ECF_LEAF | ECF_NOTHROW);
mark_used (atexit_fndecl);
pop_lang_context ();
atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
@@ -6666,7 +6656,8 @@ get_thread_atexit_node (void)
NULL_TREE);
/* Now, build the function declaration. */
- tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type);
+ tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
+ ECF_LEAF | ECF_NOTHROW);
return decay_conversion (atexit_fndecl, tf_warning_or_error);
}
@@ -6992,15 +6983,17 @@ expand_static_init (tree decl, tree init)
(acquire_name, build_function_type_list (integer_type_node,
TREE_TYPE (guard_addr),
NULL_TREE),
- NULL_TREE);
+ NULL_TREE, ECF_NOTHROW | ECF_LEAF);
if (!release_fn || !abort_fn)
vfntype = build_function_type_list (void_type_node,
TREE_TYPE (guard_addr),
NULL_TREE);
if (!release_fn)
- release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
+ release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
+ ECF_NOTHROW | ECF_LEAF);
if (!abort_fn)
- abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
+ abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
+ ECF_NOTHROW | ECF_LEAF);
inner_if_stmt = begin_if_stmt ();
finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index df43a80cbbe..db481a16761 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1364,6 +1364,47 @@ find_typenames (tree t)
return ft.typenames;
}
+/* Output the "[with ...]" clause for a template instantiation T iff
+ TEMPLATE_PARMS, TEMPLATE_ARGS and FLAGS are suitable. T may be NULL if
+ formatting a deduction/substitution diagnostic rather than an
+ instantiation. */
+
+static void
+dump_substitution (cxx_pretty_printer *pp,
+ tree t, tree template_parms, tree template_args,
+ int flags)
+{
+ if (template_parms != NULL_TREE && template_args != NULL_TREE
+ && !(flags & TFF_NO_TEMPLATE_BINDINGS))
+ {
+ vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_bracket (pp);
+ pp->translate_string ("with");
+ pp_cxx_whitespace (pp);
+ dump_template_bindings (pp, template_parms, template_args, typenames);
+ pp_cxx_right_bracket (pp);
+ }
+}
+
+/* Dump the lambda function FN including its 'mutable' qualifier and any
+ template bindings. */
+
+static void
+dump_lambda_function (cxx_pretty_printer *pp,
+ tree fn, tree template_parms, tree template_args,
+ int flags)
+{
+ /* A lambda's signature is essentially its "type". */
+ dump_type (pp, DECL_CONTEXT (fn), flags);
+ if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST))
+ {
+ pp->padding = pp_before;
+ pp_c_ws_string (pp, "mutable");
+ }
+ dump_substitution (pp, fn, template_parms, template_args, flags);
+}
+
/* Pretty print a function decl. There are several ways we want to print a
function declaration. The TFF_ bits in FLAGS tells us how to behave.
As error can only apply the '#' flag once to give 0 and 1 for V, there
@@ -1380,15 +1421,6 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
tree exceptions;
- vec<tree, va_gc> *typenames = NULL;
-
- if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
- {
- /* A lambda's signature is essentially its "type", so defer. */
- gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t)));
- dump_type (pp, DECL_CONTEXT (t), flags);
- return;
- }
flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
if (TREE_CODE (t) == TEMPLATE_DECL)
@@ -1410,10 +1442,12 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
{
template_parms = DECL_TEMPLATE_PARMS (tmpl);
t = tmpl;
- typenames = find_typenames (t);
}
}
+ if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
+ return dump_lambda_function (pp, t, template_parms, template_args, flags);
+
fntype = TREE_TYPE (t);
parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
@@ -1477,17 +1511,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
if (show_return)
dump_type_suffix (pp, TREE_TYPE (fntype), flags);
- /* If T is a template instantiation, dump the parameter binding. */
- if (template_parms != NULL_TREE && template_args != NULL_TREE
- && !(flags & TFF_NO_TEMPLATE_BINDINGS))
- {
- pp_cxx_whitespace (pp);
- pp_cxx_left_bracket (pp);
- pp_cxx_ws_string (pp, M_("with"));
- pp_cxx_whitespace (pp);
- dump_template_bindings (pp, template_parms, template_args, typenames);
- pp_cxx_right_bracket (pp);
- }
+ dump_substitution (pp, t, template_parms, template_args, flags);
}
else if (template_args)
{
@@ -2957,12 +2981,7 @@ subst_to_string (tree p)
reinit_cxx_pp ();
dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_bracket (cxx_pp);
- pp_cxx_ws_string (cxx_pp, M_("with"));
- pp_cxx_whitespace (cxx_pp);
- dump_template_bindings (cxx_pp, tparms, targs, NULL);
- pp_cxx_right_bracket (cxx_pp);
+ dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
return pp_ggc_formatted_text (cxx_pp);
}
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index be003d2994b..164b35c3a73 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -57,7 +57,9 @@ init_exception_processing (void)
/* void std::terminate (); */
push_namespace (std_identifier);
tmp = build_function_type_list (void_type_node, NULL_TREE);
- terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
+ terminate_node = build_cp_library_fn_ptr ("terminate", tmp,
+ ECF_NOTHROW | ECF_NORETURN
+ | ECF_LEAF);
TREE_THIS_VOLATILE (terminate_node) = 1;
TREE_NOTHROW (terminate_node) = 1;
pop_namespace ();
@@ -149,12 +151,13 @@ build_exc_ptr (void)
are consistent with the actual implementations in libsupc++. */
static tree
-declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
+declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
{
return push_library_fn (name, build_function_type_list (return_type,
parm_type,
NULL_TREE),
- empty_except_spec);
+ empty_except_spec,
+ ecf_flags);
}
/* Build up a call to __cxa_get_exception_ptr so that we can build a
@@ -169,10 +172,8 @@ do_get_exception_ptr (void)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void* __cxa_get_exception_ptr (void *) throw(). */
- fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
-
- if (flag_tm)
- apply_tm_attr (fn, get_identifier ("transaction_pure"));
+ fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
+ ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
}
return cp_build_function_call_nary (fn, tf_warning_or_error,
@@ -191,16 +192,17 @@ do_begin_catch (void)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void* __cxa_begin_catch (void *) throw(). */
- fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
+ fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
+ ECF_NOTHROW | ECF_LEAF);
/* Create its transactional-memory equivalent. */
if (flag_tm)
{
tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
if (!get_global_value_if_present (fn2, &fn2))
- fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
- ptr_type_node);
- apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+ fn2 = declare_library_fn (fn2, ptr_type_node,
+ ptr_type_node,
+ ECF_NOTHROW | ECF_TM_PURE | ECF_LEAF);
record_tm_replacement (fn, fn2);
}
}
@@ -238,21 +240,17 @@ do_end_catch (tree type)
fn = get_identifier ("__cxa_end_catch");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void __cxa_end_catch (). */
- fn = push_void_library_fn (fn, void_list_node);
- /* This can throw if the destructor for the exception throws. */
- TREE_NOTHROW (fn) = 0;
+ /* Declare void __cxa_end_catch ().
+ This can throw if the destructor for the exception throws. */
+ fn = push_void_library_fn (fn, void_list_node, ECF_LEAF);
/* Create its transactional-memory equivalent. */
if (flag_tm)
{
tree fn2 = get_identifier ("_ITM_cxa_end_catch");
if (!get_global_value_if_present (fn2, &fn2))
- {
- fn2 = push_void_library_fn (fn2, void_list_node);
- TREE_NOTHROW (fn2) = 0;
- }
- apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+ fn2 = push_void_library_fn (fn2, void_list_node,
+ ECF_TM_PURE | ECF_LEAF);
record_tm_replacement (fn, fn2);
}
}
@@ -631,15 +629,17 @@ do_allocate_exception (tree type)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void *__cxa_allocate_exception(size_t) throw(). */
- fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
+ fn = declare_library_fn (fn, ptr_type_node, size_type_node,
+ ECF_NOTHROW | ECF_MALLOC | ECF_LEAF);
if (flag_tm)
{
tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
if (!get_global_value_if_present (fn2, &fn2))
- fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
- size_type_node);
- apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+ fn2 = declare_library_fn (fn2, ptr_type_node,
+ size_type_node,
+ ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE
+ | ECF_LEAF);
record_tm_replacement (fn, fn2);
}
}
@@ -660,7 +660,8 @@ do_free_exception (tree ptr)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_free_exception (void *) throw(). */
- fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
+ fn = declare_library_fn (fn, void_type_node, ptr_type_node,
+ ECF_NOTHROW | ECF_LEAF);
}
return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 3ec32c580ac..156b4a1e082 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1464,7 +1464,8 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
TREE_READONLY (exp) = 0;
TREE_THIS_VOLATILE (exp) = 0;
- if (init && TREE_CODE (init) != TREE_LIST
+ if (init && init != void_type_node
+ && TREE_CODE (init) != TREE_LIST
&& !(TREE_CODE (init) == TARGET_EXPR
&& TARGET_EXPR_DIRECT_INIT_P (init))
&& !(BRACE_ENCLOSED_INITIALIZER_P (init)
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index f3094981dfb..5827540c9b2 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -739,8 +739,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
const_ptr_type_node,
tinfo_ptr, tinfo_ptr,
ptrdiff_type_node, NULL_TREE);
- dcast_fn = build_library_fn_ptr (name, tmp);
- DECL_PURE_P (dcast_fn) = 1;
+ dcast_fn = build_library_fn_ptr (name, tmp,
+ ECF_LEAF | ECF_PURE | ECF_NOTHROW);
pop_abi_namespace ();
dynamic_cast_node = dcast_fn;
}
diff --git a/gcc/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c
index 479447aa7d0..276fa1f9966 100644
--- a/gcc/cp/vtable-class-hierarchy.c
+++ b/gcc/cp/vtable-class-hierarchy.c
@@ -113,29 +113,12 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "timevar.h"
-#include "cpplib.h"
-#include "tree.h"
#include "cp-tree.h"
-#include "intl.h"
-#include "c-family/c-pragma.h"
-#include "decl.h"
-#include "flags.h"
-#include "diagnostic-core.h"
#include "output.h"
-#include "target.h"
#include "cgraph.h"
-#include "c-family/c-common.h"
-#include "c-family/c-objc.h"
-#include "plugin.h"
#include "tree-iterator.h"
#include "vtable-verify.h"
#include "gimple.h"
-#include "bitmap.h"
-#include "libiberty.h"
-
-#define MAX_SET_SIZE 5000
static int num_calls_to_regset = 0;
static int num_calls_to_regpair = 0;
@@ -508,7 +491,7 @@ build_string_from_id (tree identifier)
static void
register_construction_vtables (tree base_class, tree record_type,
- tree *vtable_ptr_array, int *num_args)
+ vec<tree> *vtable_ptr_array)
{
tree vtbl_var_decl;
@@ -587,10 +570,7 @@ register_construction_vtables (tree base_class, tree record_type,
/* Add this vtable pointer to our set of valid
pointers for the base class. */
- gcc_assert (*num_args < (MAX_SET_SIZE - 1));
-
- vtable_ptr_array[*num_args] = value;
- *num_args = *num_args + 1;
+ vtable_ptr_array->safe_push (value);
current_set_size++;
}
}
@@ -617,7 +597,7 @@ register_construction_vtables (tree base_class, tree record_type,
static void
register_other_binfo_vtables (tree binfo, tree base_class,
- tree *vtable_ptr_array, int *num_args)
+ vec<tree> *vtable_ptr_array)
{
unsigned ix;
tree base_binfo;
@@ -641,16 +621,12 @@ register_other_binfo_vtables (tree binfo, tree base_class,
base_class);
if (!already_registered)
{
- gcc_assert (*num_args < (MAX_SET_SIZE - 1));
-
- vtable_ptr_array[*num_args] = vtable_address;
- *num_args = *num_args + 1;
+ vtable_ptr_array->safe_push (vtable_address);
current_set_size++;
}
}
- register_other_binfo_vtables (base_binfo, base_class, vtable_ptr_array,
- num_args);
+ register_other_binfo_vtables (base_binfo, base_class, vtable_ptr_array);
}
}
@@ -735,7 +711,8 @@ write_out_current_set_data (tree base_class, int set_size)
if (class_data_log_fd == -1)
{
- warning (0, "Unable to open log file 'vtv_class_set_sizes.log'");
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_class_set_sizes.log%>: %m");
return;
}
@@ -775,11 +752,12 @@ build_key_buffer_arg (tree base_ptr_var_decl)
}
static void
-insert_call_to_register_set (tree class_name, int num_args,
- tree *vtbl_ptr_array, tree body, tree arg1,
+insert_call_to_register_set (tree class_name,
+ vec<tree> *vtbl_ptr_array, tree body, tree arg1,
tree arg2, tree size_hint_arg)
{
tree call_expr;
+ int num_args = vtbl_ptr_array->length();
char *array_arg_name = ACONCAT (("__vptr_array_",
IDENTIFIER_POINTER (class_name), NULL));
tree array_arg_type = build_array_type_nelts (build_pointer_type
@@ -808,7 +786,7 @@ insert_call_to_register_set (tree class_name, int num_args,
for (k = 0; k < num_args; ++k)
{
- CONSTRUCTOR_APPEND_ELT (array_elements, NULL_TREE, vtbl_ptr_array[k]);
+ CONSTRUCTOR_APPEND_ELT (array_elements, NULL_TREE, (*vtbl_ptr_array)[k]);
}
initial = build_constructor (TREE_TYPE (array_arg), array_elements);
@@ -833,14 +811,18 @@ insert_call_to_register_set (tree class_name, int num_args,
}
static void
-insert_call_to_register_pair (tree vtable_address, int num_args, tree arg1,
+insert_call_to_register_pair (vec<tree> *vtbl_ptr_array, tree arg1,
tree arg2, tree size_hint_arg, tree str1,
tree str2, tree body)
{
tree call_expr;
+ int num_args = vtbl_ptr_array->length();
+ tree vtable_address = NULL_TREE;
if (num_args == 0)
vtable_address = build_int_cst (build_pointer_type (void_type_node), 0);
+ else
+ vtable_address = (*vtbl_ptr_array)[0];
if (flag_vtv_debug)
call_expr = build_call_expr (vlt_register_pairs_fndecl, 6, arg1, arg2,
@@ -854,11 +836,12 @@ insert_call_to_register_pair (tree vtable_address, int num_args, tree arg1,
}
static void
-output_set_info (tree record_type, tree *vtbl_ptr_array, int array_size)
+output_set_info (tree record_type, vec<tree> vtbl_ptr_array)
{
static int vtv_debug_log_fd = -1;
char buffer[1024];
int bytes_written __attribute__ ((unused));
+ int array_len = vtbl_ptr_array.length();
const char *class_name =
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (record_type)));
char *file_name = get_log_file_name ("vtv_set_ptr_data.log");
@@ -868,11 +851,12 @@ output_set_info (tree record_type, tree *vtbl_ptr_array, int array_size)
O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
if (vtv_debug_log_fd == -1)
{
- warning (0, "Unable to open log file 'vtv_set_ptr_data.log'");
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_set_ptr_data.log%>: %m");
return;
}
- for (int i = 0; i < array_size; ++i)
+ for (int i = 0; i < array_len; ++i)
{
const char *vptr_name = "unknown";
int vptr_offset = 0;
@@ -911,8 +895,7 @@ static bool
register_all_pairs (tree body)
{
bool registered_at_least_one = false;
- tree vtbl_ptr_array[MAX_SET_SIZE];
- int num_vtable_args = 0;
+ vec<tree> *vtbl_ptr_array = NULL;
unsigned j;
for (j = 0; j < num_vtable_map_nodes; ++j)
@@ -938,7 +921,11 @@ register_all_pairs (tree body)
new_type = build_pointer_type (TREE_TYPE (base_ptr_var_decl));
arg1 = build1 (ADDR_EXPR, new_type, base_ptr_var_decl);
- num_vtable_args = 0;
+ /* We need a fresh vector for each iteration. */
+ if (vtbl_ptr_array)
+ vec_free (vtbl_ptr_array);
+
+ vec_alloc (vtbl_ptr_array, 10);
for (i = 0; i < num_vtable_map_nodes; ++i)
if (bitmap_bit_p (current->class_info->descendants, i))
@@ -977,25 +964,22 @@ register_all_pairs (tree body)
if (!already_registered)
{
-
- vtbl_ptr_array[num_vtable_args++] = vtable_address;
+ vtbl_ptr_array->safe_push (vtable_address);
/* Find and handle any 'extra' vtables associated
with this class, via virtual inheritance. */
register_construction_vtables (base_class, class_type,
- vtbl_ptr_array,
- &num_vtable_args);
+ vtbl_ptr_array);
/* Find and handle any 'extra' vtables associated
with this class, via multiple inheritance. */
register_other_binfo_vtables (binfo, base_class,
- vtbl_ptr_array,
- &num_vtable_args);
+ vtbl_ptr_array);
}
}
}
}
- current_set_size = num_vtable_args;
+ current_set_size = vtbl_ptr_array->length();
/* Sometimes we need to initialize the set symbol even if we are
not adding any vtable pointers to the set in the current
@@ -1009,9 +993,12 @@ register_all_pairs (tree body)
/* If we have added vtable pointers to the set in this
compilation unit, adjust the size hint for the set's hash
table appropriately. */
- if (num_vtable_args > 0)
- while ((size_t) num_vtable_args > size_hint)
- size_hint <<= 1;
+ if (vtbl_ptr_array->length() > 0)
+ {
+ unsigned len = vtbl_ptr_array->length();
+ while ((size_t) len > size_hint)
+ size_hint <<= 1;
+ }
size_hint_arg = build_int_cst (size_type_node, size_hint);
/* Get the key-buffer argument. */
@@ -1023,23 +1010,23 @@ register_all_pairs (tree body)
if (flag_vtv_debug)
output_set_info (current->class_info->class_type,
- vtbl_ptr_array, num_vtable_args);
+ *vtbl_ptr_array);
- if (num_vtable_args > 1)
+ if (vtbl_ptr_array->length() > 1)
{
- insert_call_to_register_set (current->class_name, num_vtable_args,
+ insert_call_to_register_set (current->class_name,
vtbl_ptr_array, body, arg1, arg2,
size_hint_arg);
registered_at_least_one = true;
}
- else if (num_vtable_args >= 0)
+ else
{
- if (num_vtable_args > 0
+ if (vtbl_ptr_array->length() > 0
|| (current->is_used
|| (current->registered.size() > 0)))
{
- insert_call_to_register_pair (vtbl_ptr_array[0], num_vtable_args,
+ insert_call_to_register_pair (vtbl_ptr_array,
arg1, arg2, size_hint_arg, str1,
str2, body);
registered_at_least_one = true;
@@ -1114,7 +1101,8 @@ write_out_vtv_count_data (void)
O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
if (vtv_count_log_fd == -1)
{
- warning (0, "Unable to open log file 'vtv_count_data.log'");
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_count_data.log%>: %m");
return;
}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d8206c4f8f9..1365f657cac 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6301,6 +6301,9 @@ Enable dumps from all loop optimizations.
Enable dumps from all inlining optimizations.
@item vec
Enable dumps from all vectorization optimizations.
+@item optall
+Enable dumps from all optimizations. This is a superset of
+the optimization groups listed above.
@end table
For example,
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 9c97512e799..6f15634ab7b 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -259,16 +259,16 @@ dump_open_alternate_stream (struct dump_file_info *dfi)
void
dump_loc (int dump_kind, FILE *dfile, source_location loc)
{
- /* Currently vectorization passes print location information. */
if (dump_kind)
{
if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
- fprintf (dfile, "\n%s:%d: note: ", LOCATION_FILE (loc),
- LOCATION_LINE (loc));
+ fprintf (dfile, "\n%s:%d:%d: note: ", LOCATION_FILE (loc),
+ LOCATION_LINE (loc), LOCATION_COLUMN (loc));
else if (current_function_decl)
- fprintf (dfile, "\n%s:%d: note: ",
+ fprintf (dfile, "\n%s:%d:%d: note: ",
DECL_SOURCE_FILE (current_function_decl),
- DECL_SOURCE_LINE (current_function_decl));
+ DECL_SOURCE_LINE (current_function_decl),
+ DECL_SOURCE_COLUMN (current_function_decl));
}
}
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index da079bad748..ddc770ab947 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -98,8 +98,9 @@ enum tree_dump_index
#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */
#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */
#define OPTGROUP_VEC (1 << 4) /* Vectorization passes */
+#define OPTGROUP_OTHER (1 << 5) /* All other passes */
#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \
- | OPTGROUP_VEC)
+ | OPTGROUP_VEC | OPTGROUP_OTHER)
/* Define a tree dump switch. */
struct dump_file_info
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7e8326b8ba5..5fbe33107f2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2013-08-29 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/52243
+ * trans-expr.c (is_runtime_conformable): New function.
+ * gfc_trans_assignment_1: Use it.
+
2013-08-26 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/58146
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index dd4c8fc62c1..0ecfdfce469 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -7738,6 +7738,105 @@ alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
}
}
+/* Check for assignments of the type
+
+ a = a + 4
+
+ to make sure we do not check for reallocation unneccessarily. */
+
+
+static bool
+is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
+{
+ gfc_actual_arglist *a;
+ gfc_expr *e1, *e2;
+
+ switch (expr2->expr_type)
+ {
+ case EXPR_VARIABLE:
+ return gfc_dep_compare_expr (expr1, expr2) == 0;
+
+ case EXPR_FUNCTION:
+ if (expr2->value.function.esym
+ && expr2->value.function.esym->attr.elemental)
+ {
+ for (a = expr2->value.function.actual; a != NULL; a = a->next)
+ {
+ e1 = a->expr;
+ if (e1->rank > 0 && !is_runtime_conformable (expr1, e1))
+ return false;
+ }
+ return true;
+ }
+ else if (expr2->value.function.isym
+ && expr2->value.function.isym->elemental)
+ {
+ for (a = expr2->value.function.actual; a != NULL; a = a->next)
+ {
+ e1 = a->expr;
+ if (e1->rank > 0 && !is_runtime_conformable (expr1, e1))
+ return false;
+ }
+ return true;
+ }
+
+ break;
+
+ case EXPR_OP:
+ switch (expr2->value.op.op)
+ {
+ case INTRINSIC_NOT:
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ case INTRINSIC_PARENTHESES:
+ return is_runtime_conformable (expr1, expr2->value.op.op1);
+
+ case INTRINSIC_PLUS:
+ case INTRINSIC_MINUS:
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER:
+ case INTRINSIC_AND:
+ case INTRINSIC_OR:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ case INTRINSIC_GT:
+ case INTRINSIC_GE:
+ case INTRINSIC_LT:
+ case INTRINSIC_LE:
+ case INTRINSIC_EQ_OS:
+ case INTRINSIC_NE_OS:
+ case INTRINSIC_GT_OS:
+ case INTRINSIC_GE_OS:
+ case INTRINSIC_LT_OS:
+ case INTRINSIC_LE_OS:
+
+ e1 = expr2->value.op.op1;
+ e2 = expr2->value.op.op2;
+
+ if (e1->rank == 0 && e2->rank > 0)
+ return is_runtime_conformable (expr1, e2);
+ else if (e1->rank > 0 && e2->rank == 0)
+ return is_runtime_conformable (expr1, e1);
+ else if (e1->rank > 0 && e2->rank > 0)
+ return is_runtime_conformable (expr1, e1)
+ && is_runtime_conformable (expr1, e2);
+ break;
+
+ default:
+ break;
+
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
/* Subroutine of gfc_trans_assignment that actually scalarizes the
assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
@@ -7935,7 +8034,8 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
&& gfc_is_reallocatable_lhs (expr1)
&& !gfc_expr_attr (expr1).codimension
&& !gfc_is_coindexed (expr1)
- && expr2->rank)
+ && expr2->rank
+ && !is_runtime_conformable (expr1, expr2))
{
realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
ompws_flags &= ~OMPWS_SCALARIZER_WS;
diff --git a/gcc/function.h b/gcc/function.h
index c651f5037f8..d1f4ffc1fd4 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -650,6 +650,14 @@ struct GTY(()) function {
adjusts one of its arguments and forwards to another
function. */
unsigned int is_thunk : 1;
+
+ /* Nonzero if the current function contains any loops with
+ loop->force_vect set. */
+ unsigned int has_force_vect_loops : 1;
+
+ /* Nonzero if the current function contains any loops with
+ nonzero value in loop->simduid. */
+ unsigned int has_simduid_loops : 1;
};
/* Add the decl D to the local_decls list of FUN. */
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
new file mode 100644
index 00000000000..3d69b11bfe9
--- /dev/null
+++ b/gcc/gdbhooks.py
@@ -0,0 +1,397 @@
+# Python hooks for gdb for debugging GCC
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# Contributed by David Malcolm <dmalcolm@redhat.com>
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+
+# GCC is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+"""
+Enabling the debugging hooks
+----------------------------
+gcc/configure (from configure.ac) generates a .gdbinit within the "gcc"
+subdirectory of the build directory, and when run by gdb, this imports
+gcc/gdbhooks.py from the source directory, injecting useful Python code
+into gdb.
+
+You may see a message from gdb of the form:
+ "path-to-build/gcc/.gdbinit" auto-loading has been declined by your `auto-load safe-path'
+as a protection against untrustworthy python scripts. See
+ http://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading-safe-path.html
+
+The fix is to mark the paths of the build/gcc directory as trustworthy.
+An easy way to do so is by adding the following to your ~/.gdbinit script:
+ add-auto-load-safe-path /absolute/path/to/build/gcc
+for the build directories for your various checkouts of gcc.
+
+If it's working, you should see the message:
+ Successfully loaded GDB hooks for GCC
+as gdb starts up.
+
+During development, I've been manually invoking the code in this way, as a
+precanned way of printing a variety of different kinds of value:
+
+ gdb \
+ -ex "break expand_gimple_stmt" \
+ -ex "run" \
+ -ex "bt" \
+ --args \
+ ./cc1 foo.c -O3
+
+Examples of output using the pretty-printers
+--------------------------------------------
+Pointer values are generally shown in the form:
+ <type address extra_info>
+
+For example, an opt_pass* might appear as:
+ (gdb) p pass
+ $2 = <opt_pass* 0x188b600 "expand"(170)>
+
+The name of the pass is given ("expand"), together with the
+static_pass_number.
+
+Note that you can dereference the pointer in the normal way:
+ (gdb) p *pass
+ $4 = {type = RTL_PASS, name = 0x120a312 "expand",
+ [etc, ...snipped...]
+
+and you can suppress pretty-printers using /r (for "raw"):
+ (gdb) p /r pass
+ $3 = (opt_pass *) 0x188b600
+
+Basic blocks are shown with their index in parentheses, apart from the
+CFG's entry and exit blocks, which are given as "ENTRY" and "EXIT":
+ (gdb) p bb
+ $9 = <basic_block 0x7ffff041f1a0 (2)>
+ (gdb) p cfun->cfg->x_entry_block_ptr
+ $10 = <basic_block 0x7ffff041f0d0 (ENTRY)>
+ (gdb) p cfun->cfg->x_exit_block_ptr
+ $11 = <basic_block 0x7ffff041f138 (EXIT)>
+
+CFG edges are shown with the src and dest blocks given in parentheses:
+ (gdb) p e
+ $1 = <edge 0x7ffff043f118 (ENTRY -> 6)>
+
+Tree nodes are printed using Python code that emulates print_node_brief,
+running in gdb, rather than in the inferior:
+ (gdb) p cfun->decl
+ $1 = <function_decl 0x7ffff0420b00 foo>
+For usability, the type is printed first (e.g. "function_decl"), rather
+than just "tree".
+
+RTL expressions use a kludge: they are pretty-printed by injecting
+calls into print-rtl.c into the inferior:
+ Value returned is $1 = (note 9 8 10 [bb 3] NOTE_INSN_BASIC_BLOCK)
+ (gdb) p $1
+ $2 = (note 9 8 10 [bb 3] NOTE_INSN_BASIC_BLOCK)
+ (gdb) p /r $1
+ $3 = (rtx_def *) 0x7ffff043e140
+This won't work for coredumps, and probably in other circumstances, but
+it's a quick way of getting lots of debuggability quickly.
+
+Callgraph nodes are printed with the name of the function decl, if
+available:
+ (gdb) frame 5
+ #5 0x00000000006c288a in expand_function (node=<cgraph_node* 0x7ffff0312720 "foo">) at ../../src/gcc/cgraphunit.c:1594
+ 1594 execute_pass_list (g->get_passes ()->all_passes);
+ (gdb) p node
+ $1 = <cgraph_node* 0x7ffff0312720 "foo">
+"""
+import re
+
+import gdb
+import gdb.printing
+import gdb.types
+
+# Convert "enum tree_code" (tree.def and tree.h) to a dict:
+tree_code_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code'))
+
+# ...and look up specific values for use later:
+IDENTIFIER_NODE = tree_code_dict['IDENTIFIER_NODE']
+TYPE_DECL = tree_code_dict['TYPE_DECL']
+
+# Similarly for "enum tree_code_class" (tree.h):
+tree_code_class_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code_class'))
+tcc_type = tree_code_class_dict['tcc_type']
+tcc_declaration = tree_code_class_dict['tcc_declaration']
+
+class Tree:
+ """
+ Wrapper around a gdb.Value for a tree, with various methods
+ corresponding to macros in gcc/tree.h
+ """
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def is_nonnull(self):
+ return long(self.gdbval)
+
+ def TREE_CODE(self):
+ """
+ Get gdb.Value corresponding to TREE_CODE (self)
+ as per:
+ #define TREE_CODE(NODE) ((enum tree_code) (NODE)->base.code)
+ """
+ return self.gdbval['base']['code']
+
+ def DECL_NAME(self):
+ """
+ Get Tree instance corresponding to DECL_NAME (self)
+ """
+ return Tree(self.gdbval['decl_minimal']['name'])
+
+ def TYPE_NAME(self):
+ """
+ Get Tree instance corresponding to result of TYPE_NAME (self)
+ """
+ return Tree(self.gdbval['type_common']['name'])
+
+ def IDENTIFIER_POINTER(self):
+ """
+ Get str correspoinding to result of IDENTIFIER_NODE (self)
+ """
+ return self.gdbval['identifier']['id']['str'].string()
+
+class TreePrinter:
+ "Prints a tree"
+
+ def __init__ (self, gdbval):
+ self.gdbval = gdbval
+ self.node = Tree(gdbval)
+
+ def to_string (self):
+ # like gcc/print-tree.c:print_node_brief
+ # #define TREE_CODE(NODE) ((enum tree_code) (NODE)->base.code)
+ # tree_code_name[(int) TREE_CODE (node)])
+ if long(self.gdbval) == 0:
+ return '<tree 0x0>'
+
+ val_TREE_CODE = self.node.TREE_CODE()
+
+ # extern const enum tree_code_class tree_code_type[];
+ # #define TREE_CODE_CLASS(CODE) tree_code_type[(int) (CODE)]
+
+ val_tree_code_type = gdb.parse_and_eval('tree_code_type')
+ val_tclass = val_tree_code_type[val_TREE_CODE]
+
+ val_tree_code_name = gdb.parse_and_eval('tree_code_name')
+ val_code_name = val_tree_code_name[long(val_TREE_CODE)]
+ #print val_code_name.string()
+
+ result = '<%s 0x%x' % (val_code_name.string(), long(self.gdbval))
+ if long(val_tclass) == tcc_declaration:
+ tree_DECL_NAME = self.node.DECL_NAME()
+ if tree_DECL_NAME.is_nonnull():
+ result += ' %s' % tree_DECL_NAME.IDENTIFIER_POINTER()
+ else:
+ pass # TODO: labels etc
+ elif long(val_tclass) == tcc_type:
+ tree_TYPE_NAME = Tree(self.gdbval['type_common']['name'])
+ if tree_TYPE_NAME.is_nonnull():
+ if tree_TYPE_NAME.TREE_CODE() == IDENTIFIER_NODE:
+ result += ' %s' % tree_TYPE_NAME.IDENTIFIER_POINTER()
+ elif tree_TYPE_NAME.TREE_CODE() == TYPE_DECL:
+ if tree_TYPE_NAME.DECL_NAME().is_nonnull():
+ result += ' %s' % tree_TYPE_NAME.DECL_NAME().IDENTIFIER_POINTER()
+ if self.node.TREE_CODE() == IDENTIFIER_NODE:
+ result += ' %s' % self.node.IDENTIFIER_POINTER()
+ # etc
+ result += '>'
+ return result
+
+######################################################################
+# Callgraph pretty-printers
+######################################################################
+
+class CGraphNodePrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<cgraph_node* 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ # symtab_node_name calls lang_hooks.decl_printable_name
+ # default implementation (lhd_decl_printable_name) is:
+ # return IDENTIFIER_POINTER (DECL_NAME (decl));
+ symbol = self.gdbval['symbol']
+ tree_decl = Tree(symbol['decl'])
+ result += ' "%s"' % tree_decl.DECL_NAME().IDENTIFIER_POINTER()
+ result += '>'
+ return result
+
+######################################################################
+
+class GimplePrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ if long(self.gdbval) == 0:
+ return '<gimple 0x0>'
+ val_gimple_code = self.gdbval['gsbase']['code']
+ val_gimple_code_name = gdb.parse_and_eval('gimple_code_name')
+ val_code_name = val_gimple_code_name[long(val_gimple_code)]
+ result = '<%s 0x%x' % (val_code_name.string(),
+ long(self.gdbval))
+ result += '>'
+ return result
+
+######################################################################
+# CFG pretty-printers
+######################################################################
+
+def bb_index_to_str(index):
+ if index == 0:
+ return 'ENTRY'
+ elif index == 1:
+ return 'EXIT'
+ else:
+ return '%i' % index
+
+class BasicBlockPrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<basic_block 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ result += ' (%s)' % bb_index_to_str(long(self.gdbval['index']))
+ result += '>'
+ return result
+
+class CfgEdgePrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<edge 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ src = bb_index_to_str(long(self.gdbval['src']['index']))
+ dest = bb_index_to_str(long(self.gdbval['dest']['index']))
+ result += ' (%s -> %s)' % (src, dest)
+ result += '>'
+ return result
+
+######################################################################
+
+class Rtx:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def GET_CODE(self):
+ return self.gdbval['code']
+
+def GET_RTX_LENGTH(code):
+ val_rtx_length = gdb.parse_and_eval('rtx_length')
+ return long(val_rtx_length[code])
+
+def GET_RTX_NAME(code):
+ val_rtx_name = gdb.parse_and_eval('rtx_name')
+ return val_rtx_name[code].string()
+
+def GET_RTX_FORMAT(code):
+ val_rtx_format = gdb.parse_and_eval('rtx_format')
+ return val_rtx_format[code].string()
+
+class RtxPrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+ self.rtx = Rtx(gdbval)
+
+ def to_string (self):
+ """
+ For now, a cheap kludge: invoke the inferior's print
+ function to get a string to use the user, and return an empty
+ string for gdb
+ """
+ # We use print_inline_rtx to avoid a trailing newline
+ gdb.execute('call print_inline_rtx (stderr, (const_rtx) %s, 0)'
+ % long(self.gdbval))
+ return ''
+
+ # or by hand; based on gcc/print-rtl.c:print_rtx
+ result = ('<rtx_def 0x%x'
+ % (long(self.gdbval)))
+ code = self.rtx.GET_CODE()
+ result += ' (%s' % GET_RTX_NAME(code)
+ format_ = GET_RTX_FORMAT(code)
+ for i in range(GET_RTX_LENGTH(code)):
+ print format_[i]
+ result += ')>'
+ return result
+
+######################################################################
+
+class PassPrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<opt_pass* 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ result += (' "%s"(%i)'
+ % (self.gdbval['name'].string(),
+ long(self.gdbval['static_pass_number'])))
+ result += '>'
+ return result
+
+######################################################################
+
+# TODO:
+# * vec
+# * hashtab
+# * location_t
+
+class GdbSubprinter(gdb.printing.SubPrettyPrinter):
+ def __init__(self, name, str_type_, class_):
+ super(GdbSubprinter, self).__init__(name)
+ self.str_type_ = str_type_
+ self.class_ = class_
+
+class GdbPrettyPrinters(gdb.printing.PrettyPrinter):
+ def __init__(self, name):
+ super(GdbPrettyPrinters, self).__init__(name, [])
+
+ def add_printer(self, name, exp, class_):
+ self.subprinters.append(GdbSubprinter(name, exp, class_))
+
+ def __call__(self, gdbval):
+ type_ = gdbval.type.unqualified()
+ str_type_ = str(type_)
+ for printer in self.subprinters:
+ if printer.enabled and str_type_ == printer.str_type_:
+ return printer.class_(gdbval)
+
+ # Couldn't find a pretty printer (or it was disabled):
+ return None
+
+
+def build_pretty_printer():
+ pp = GdbPrettyPrinters('gcc')
+ pp.add_printer('tree', 'tree', TreePrinter)
+ pp.add_printer('cgraph_node', 'cgraph_node *', CGraphNodePrinter)
+ pp.add_printer('gimple', 'gimple', GimplePrinter)
+ pp.add_printer('basic_block', 'basic_block', BasicBlockPrinter)
+ pp.add_printer('edge', 'edge', CfgEdgePrinter)
+ pp.add_printer('rtx_def', 'rtx_def *', RtxPrinter)
+ pp.add_printer('opt_pass', 'opt_pass *', PassPrinter)
+ return pp
+
+gdb.printing.register_pretty_printer(
+ gdb.current_objfile(),
+ build_pretty_printer())
+
+print('Successfully loaded GDB hooks for GCC')
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index e6eb5d4ba22..3ab558cae38 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1088,8 +1088,20 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
if (flags & TDF_RAW)
{
- dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
- gimple_omp_body (gs));
+ const char *kind;
+ switch (gimple_omp_for_kind (gs))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ kind = "";
+ break;
+ case GF_OMP_FOR_KIND_SIMD:
+ kind = " simd";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ dump_gimple_fmt (buffer, spc, flags, "%G%s <%+BODY <%S>%nCLAUSES <", gs,
+ kind, gimple_omp_body (gs));
dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
dump_gimple_fmt (buffer, spc, flags, " >,");
for (i = 0; i < gimple_omp_for_collapse (gs); i++)
@@ -1105,7 +1117,17 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
}
else
{
- pp_string (buffer, "#pragma omp for");
+ switch (gimple_omp_for_kind (gs))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ pp_string (buffer, "#pragma omp for");
+ break;
+ case GF_OMP_FOR_KIND_SIMD:
+ pp_string (buffer, "#pragma omp simd");
+ break;
+ default:
+ gcc_unreachable ();
+ }
dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
for (i = 0; i < gimple_omp_for_collapse (gs); i++)
{
diff --git a/gcc/gimple.c b/gcc/gimple.c
index ae9fca716ca..4dbcdda31b9 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -902,19 +902,21 @@ gimple_build_omp_critical (gimple_seq body, tree name)
/* Build a GIMPLE_OMP_FOR statement.
BODY is sequence of statements inside the for loop.
+ KIND is the `for' variant.
CLAUSES, are any of the OMP loop construct's clauses: private, firstprivate,
lastprivate, reductions, ordered, schedule, and nowait.
COLLAPSE is the collapse count.
PRE_BODY is the sequence of statements that are loop invariant. */
gimple
-gimple_build_omp_for (gimple_seq body, tree clauses, size_t collapse,
+gimple_build_omp_for (gimple_seq body, int kind, tree clauses, size_t collapse,
gimple_seq pre_body)
{
gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0);
if (body)
gimple_omp_set_body (p, body);
gimple_omp_for_set_clauses (p, clauses);
+ gimple_omp_for_set_kind (p, kind);
p->gimple_omp_for.collapse = collapse;
p->gimple_omp_for.iter
= ggc_alloc_cleared_vec_gimple_omp_for_iter (collapse);
diff --git a/gcc/gimple.def b/gcc/gimple.def
index acad572e353..f3652f4e78f 100644
--- a/gcc/gimple.def
+++ b/gcc/gimple.def
@@ -287,7 +287,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
BODY is a the sequence of statements to be executed by all threads.
- CLAUSES is a TREE_LIST node with all the clauses.
+ CLAUSES is an OMP_CLAUSE chain with all the clauses.
CHILD_FN is set when outlining the body of the parallel region.
All the statements in BODY are moved into this newly created
@@ -306,7 +306,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
BODY is a the sequence of statements to be executed by all threads.
- CLAUSES is a TREE_LIST node with all the clauses.
+ CLAUSES is an OMP_CLAUSE chain with all the clauses.
CHILD_FN is set when outlining the body of the explicit task region.
All the statements in BODY are moved into this newly created
@@ -334,7 +334,7 @@ DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
/* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
BODY is the sequence of statements in the sections body.
- CLAUSES is a TREE_LIST node holding the list of associated clauses.
+ CLAUSES is an OMP_CLAUSE chain holding the list of associated clauses.
CONTROL is a VAR_DECL used for deciding which of the sections
to execute. */
DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS)
@@ -346,7 +346,7 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
BODY is the sequence of statements inside the single section.
- CLAUSES is a TREE_LIST node holding the associated clauses. */
+ CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
diff --git a/gcc/gimple.h b/gcc/gimple.h
index b0399370358..9f29561eb37 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -110,6 +110,9 @@ enum gf_mask {
GF_CALL_ALLOCA_FOR_VAR = 1 << 5,
GF_CALL_INTERNAL = 1 << 6,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
+ GF_OMP_FOR_KIND_MASK = 3 << 0,
+ GF_OMP_FOR_KIND_FOR = 0 << 0,
+ GF_OMP_FOR_KIND_SIMD = 1 << 0,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
a thread synchronization via some sort of barrier. The exact barrier
@@ -799,7 +802,7 @@ gimple gimple_build_switch_nlabels (unsigned, tree, tree);
gimple gimple_build_switch (tree, tree, vec<tree> );
gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree);
-gimple gimple_build_omp_for (gimple_seq, tree, size_t, gimple_seq);
+gimple gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq);
gimple gimple_build_omp_critical (gimple_seq, tree);
gimple gimple_build_omp_section (gimple_seq);
gimple gimple_build_omp_continue (tree, tree);
@@ -3948,6 +3951,27 @@ gimple_omp_critical_set_name (gimple gs, tree name)
}
+/* Return the kind of OMP for statemement. */
+
+static inline int
+gimple_omp_for_kind (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
+ return (gimple_omp_subcode (g) & GF_OMP_FOR_KIND_MASK);
+}
+
+
+/* Set the OMP for kind. */
+
+static inline void
+gimple_omp_for_set_kind (gimple g, int kind)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
+ g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_FOR_KIND_MASK)
+ | (kind & GF_OMP_FOR_KIND_MASK);
+}
+
+
/* Return the clauses associated with OMP_FOR GS. */
static inline tree
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4d39d539f2d..3b3adb34317 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -58,14 +58,17 @@ enum gimplify_omp_var_data
GOVD_LOCAL = 128,
GOVD_DEBUG_PRIVATE = 256,
GOVD_PRIVATE_OUTER_REF = 512,
+ GOVD_LINEAR = 2048,
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
- | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
+ | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
+ | GOVD_LOCAL)
};
enum omp_region_type
{
ORT_WORKSHARE = 0,
+ ORT_SIMD = 1,
ORT_PARALLEL = 2,
ORT_COMBINED_PARALLEL = 3,
ORT_TASK = 4,
@@ -710,7 +713,9 @@ gimple_add_tmp_var (tree tmp)
if (gimplify_omp_ctxp)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- while (ctx && ctx->region_type == ORT_WORKSHARE)
+ while (ctx
+ && (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD))
ctx = ctx->outer_context;
if (ctx)
omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
@@ -2061,7 +2066,9 @@ gimplify_var_or_parm_decl (tree *expr_p)
&& decl_function_context (decl) != current_function_decl)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- while (ctx && ctx->region_type == ORT_WORKSHARE)
+ while (ctx
+ && (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD))
ctx = ctx->outer_context;
if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
{
@@ -4702,6 +4709,7 @@ is_gimple_stmt (tree t)
case STATEMENT_LIST:
case OMP_PARALLEL:
case OMP_FOR:
+ case OMP_SIMD:
case OMP_SECTIONS:
case OMP_SECTION:
case OMP_SINGLE:
@@ -5714,7 +5722,8 @@ omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
else
return;
}
- else if (ctx->region_type != ORT_WORKSHARE)
+ else if (ctx->region_type != ORT_WORKSHARE
+ && ctx->region_type != ORT_SIMD)
omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
ctx = ctx->outer_context;
@@ -5806,7 +5815,8 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
FIRSTPRIVATE and LASTPRIVATE. */
nflags = n->value | flags;
gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS)
- == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE));
+ == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)
+ || (flags & GOVD_DATA_SHARE_CLASS) == 0);
n->value = nflags;
return;
}
@@ -5870,7 +5880,10 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
}
}
- splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
+ if (n != NULL)
+ n->value |= flags;
+ else
+ splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
}
/* Notice a threadprivate variable DECL used in OpenMP context CTX.
@@ -5936,7 +5949,8 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
enum omp_clause_default_kind default_kind, kind;
struct gimplify_omp_ctx *octx;
- if (ctx->region_type == ORT_WORKSHARE)
+ if (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD)
goto do_outer;
/* ??? Some compiler-generated variables (like SAVE_EXPRs) could be
@@ -6049,7 +6063,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
to the contrary in the innermost scope, generate an error. */
static bool
-omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
+omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, bool simd)
{
splay_tree_node n;
@@ -6060,8 +6074,12 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
{
if (ctx == gimplify_omp_ctxp)
{
- error ("iteration variable %qE should be private",
- DECL_NAME (decl));
+ if (simd)
+ error ("iteration variable %qE is predetermined linear",
+ DECL_NAME (decl));
+ else
+ error ("iteration variable %qE should be private",
+ DECL_NAME (decl));
n->value = GOVD_PRIVATE;
return true;
}
@@ -6079,16 +6097,26 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
else if ((n->value & GOVD_REDUCTION) != 0)
error ("iteration variable %qE should not be reduction",
DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_LASTPRIVATE) != 0)
+ error ("iteration variable %qE should not be lastprivate",
+ DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_PRIVATE) != 0)
+ error ("iteration variable %qE should not be private",
+ DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_LINEAR) != 0)
+ error ("iteration variable %qE is predetermined linear",
+ DECL_NAME (decl));
}
return (ctx == gimplify_omp_ctxp
|| (ctx->region_type == ORT_COMBINED_PARALLEL
&& gimplify_omp_ctxp->outer_context == ctx));
}
- if (ctx->region_type != ORT_WORKSHARE)
+ if (ctx->region_type != ORT_WORKSHARE
+ && ctx->region_type != ORT_SIMD)
return false;
else if (ctx->outer_context)
- return omp_is_private (ctx->outer_context, decl);
+ return omp_is_private (ctx->outer_context, decl, simd);
return false;
}
@@ -6113,7 +6141,8 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
if (n != NULL)
return (n->value & GOVD_SHARED) == 0;
}
- while (ctx->region_type == ORT_WORKSHARE);
+ while (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD);
return false;
}
@@ -6166,6 +6195,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
check_non_private = "reduction";
goto do_add;
+ case OMP_CLAUSE_LINEAR:
+ if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
+ is_gimple_val, fb_rvalue) == GS_ERROR)
+ {
+ remove = true;
+ break;
+ }
+ flags = GOVD_LINEAR | GOVD_EXPLICIT;
+ goto do_add;
do_add:
decl = OMP_CLAUSE_DECL (c);
@@ -6264,6 +6302,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
case OMP_CLAUSE_DEFAULT:
@@ -6321,7 +6360,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
splay_tree_node on
= splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
- | GOVD_PRIVATE | GOVD_REDUCTION)) != 0)
+ | GOVD_PRIVATE | GOVD_REDUCTION
+ | GOVD_LINEAR)) != 0)
break;
ctx = ctx->outer_context;
}
@@ -6334,6 +6374,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
code = OMP_CLAUSE_PRIVATE;
else if (flags & GOVD_FIRSTPRIVATE)
code = OMP_CLAUSE_FIRSTPRIVATE;
+ else if (flags & GOVD_LASTPRIVATE)
+ code = OMP_CLAUSE_LASTPRIVATE;
else
gcc_unreachable ();
@@ -6366,6 +6408,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LINEAR:
decl = OMP_CLAUSE_DECL (c);
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
remove = !(n->value & GOVD_SEEN);
@@ -6381,6 +6424,31 @@ gimplify_adjust_omp_clauses (tree *list_p)
OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
}
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && ctx->outer_context
+ && !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+ && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+ && !is_global_var (decl))
+ {
+ if (ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
+ {
+ n = splay_tree_lookup (ctx->outer_context->variables,
+ (splay_tree_key) decl);
+ if (n == NULL
+ || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
+ {
+ int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+ ? GOVD_LASTPRIVATE : GOVD_SHARED;
+ if (n == NULL)
+ omp_add_variable (ctx->outer_context, decl,
+ flags | GOVD_SEEN);
+ else
+ n->value |= flags | GOVD_SEEN;
+ }
+ }
+ else
+ omp_notice_variable (ctx->outer_context, decl, true);
+ }
}
break;
@@ -6406,6 +6474,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
default:
@@ -6509,14 +6578,40 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gimple gfor;
gimple_seq for_body, for_pre_body;
int i;
+ bool simd;
+ bitmap has_decl_expr = NULL;
for_stmt = *expr_p;
+ simd = TREE_CODE (for_stmt) == OMP_SIMD;
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
- ORT_WORKSHARE);
+ simd ? ORT_SIMD : ORT_WORKSHARE);
/* Handle OMP_FOR_INIT. */
for_pre_body = NULL;
+ if (simd && OMP_FOR_PRE_BODY (for_stmt))
+ {
+ has_decl_expr = BITMAP_ALLOC (NULL);
+ if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
+ == VAR_DECL)
+ {
+ t = OMP_FOR_PRE_BODY (for_stmt);
+ bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
+ }
+ else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator si;
+ for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
+ tsi_next (&si))
+ {
+ t = tsi_stmt (si);
+ if (TREE_CODE (t) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
+ bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
+ }
+ }
+ }
gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
@@ -6535,7 +6630,44 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
|| POINTER_TYPE_P (TREE_TYPE (decl)));
/* Make sure the iteration variable is private. */
- if (omp_is_private (gimplify_omp_ctxp, decl))
+ tree c = NULL_TREE;
+ if (simd)
+ {
+ splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
+ (splay_tree_key)decl);
+ omp_is_private (gimplify_omp_ctxp, decl, simd);
+ if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
+ omp_notice_variable (gimplify_omp_ctxp, decl, true);
+ else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
+ if (has_decl_expr
+ && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
+ OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
+ OMP_FOR_CLAUSES (for_stmt) = c;
+ omp_add_variable (gimplify_omp_ctxp, decl,
+ GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
+ }
+ else
+ {
+ bool lastprivate
+ = (!has_decl_expr
+ || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
+ c = build_omp_clause (input_location,
+ lastprivate ? OMP_CLAUSE_LASTPRIVATE
+ : OMP_CLAUSE_PRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
+ omp_add_variable (gimplify_omp_ctxp, decl,
+ (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
+ | GOVD_SEEN);
+ c = NULL_TREE;
+ }
+ }
+ else if (omp_is_private (gimplify_omp_ctxp, decl, simd))
omp_notice_variable (gimplify_omp_ctxp, decl, true);
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
@@ -6577,6 +6709,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), 1);
+ if (c)
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
@@ -6585,6 +6719,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), -1);
+ if (c)
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
@@ -6618,6 +6754,20 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
is_gimple_val, fb_rvalue);
ret = MIN (ret, tret);
+ if (c)
+ {
+ OMP_CLAUSE_LINEAR_STEP (c) = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == MINUS_EXPR)
+ {
+ t = TREE_OPERAND (t, 1);
+ OMP_CLAUSE_LINEAR_STEP (c)
+ = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
+ tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
+ &for_pre_body, NULL,
+ is_gimple_val, fb_rvalue);
+ ret = MIN (ret, tret);
+ }
+ }
break;
default:
@@ -6648,11 +6798,21 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
}
+ BITMAP_FREE (has_decl_expr);
+
gimplify_and_add (OMP_FOR_BODY (for_stmt), &for_body);
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
- gfor = gimple_build_omp_for (for_body, OMP_FOR_CLAUSES (for_stmt),
+ int kind;
+ switch (TREE_CODE (for_stmt))
+ {
+ case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
+ case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
+ default:
+ gcc_unreachable ();
+ }
+ gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (for_stmt),
TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
for_pre_body);
@@ -6669,7 +6829,10 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
gimplify_seq_add_stmt (pre_p, gfor);
- return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
+ if (ret != GS_ALL_DONE)
+ return GS_ERROR;
+ *expr_p = NULL_TREE;
+ return GS_ALL_DONE;
}
/* Gimplify the gross structure of other OpenMP worksharing constructs.
@@ -7587,6 +7750,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
break;
case OMP_FOR:
+ case OMP_SIMD:
ret = gimplify_omp_for (expr_p, pre_p);
break;
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index d2997de3da8..c730ecaa183 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,9 @@
+2013-08-28 Ian Lance Taylor <iant@google.com>
+
+ * go-gcc.cc (Gcc_backend::immutable_struct): Set TREE_PUBLIC if
+ the struct is not hidden.
+ (Gcc_backend::immutable_struct_set_init): Don't set TREE_PUBLIC.
+
2013-08-06 Ian Lance Taylor <iant@google.com>
* go-gcc.cc (Gcc_backend::immutable_struct_set_init): Use
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 1ecfaffd73a..025bb2bdca0 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -1475,8 +1475,8 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
// Create a named immutable initialized data structure.
Bvariable*
-Gcc_backend::immutable_struct(const std::string& name, bool, bool,
- Btype* btype, Location location)
+Gcc_backend::immutable_struct(const std::string& name, bool is_hidden,
+ bool, Btype* btype, Location location)
{
tree type_tree = btype->get_tree();
if (type_tree == error_mark_node)
@@ -1490,6 +1490,8 @@ Gcc_backend::immutable_struct(const std::string& name, bool, bool,
TREE_CONSTANT(decl) = 1;
TREE_USED(decl) = 1;
DECL_ARTIFICIAL(decl) = 1;
+ if (!is_hidden)
+ TREE_PUBLIC(decl) = 1;
// We don't call rest_of_decl_compilation until we have the
// initializer.
@@ -1503,8 +1505,7 @@ Gcc_backend::immutable_struct(const std::string& name, bool, bool,
void
Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
- bool is_hidden, bool is_common, Btype*,
- Location,
+ bool, bool is_common, Btype*, Location,
Bexpression* initializer)
{
tree decl = var->get_tree();
@@ -1515,12 +1516,7 @@ Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
DECL_INITIAL(decl) = init_tree;
// We can't call make_decl_one_only until we set DECL_INITIAL.
- if (!is_common)
- {
- if (!is_hidden)
- TREE_PUBLIC(decl) = 1;
- }
- else
+ if (is_common)
make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
// These variables are often unneeded in the final program, so put
diff --git a/gcc/gtm-builtins.def b/gcc/gtm-builtins.def
index 171019ef7d0..e2bc081b054 100644
--- a/gcc/gtm-builtins.def
+++ b/gcc/gtm-builtins.def
@@ -28,7 +28,7 @@ DEF_TM_BUILTIN (BUILT_IN_TM_MALLOC, "_ITM_malloc",
DEF_TM_BUILTIN (BUILT_IN_TM_CALLOC, "_ITM_calloc",
BT_FN_PTR_SIZE_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
DEF_TM_BUILTIN (BUILT_IN_TM_FREE, "_ITM_free",
- BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LIST)
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
/* Logging builtins. */
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_1, "_ITM_LU1",
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index b841abd328e..983efeb751b 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -109,6 +109,30 @@ expand_STORE_LANES (gimple stmt)
expand_insn (get_multi_vector_move (type, vec_store_lanes_optab), 2, ops);
}
+/* This should get expanded in adjust_simduid_builtins. */
+
+static void
+expand_GOMP_SIMD_LANE (gimple stmt ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+}
+
+/* This should get expanded in adjust_simduid_builtins. */
+
+static void
+expand_GOMP_SIMD_VF (gimple stmt ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+}
+
+/* This should get expanded in adjust_simduid_builtins. */
+
+static void
+expand_GOMP_SIMD_LAST_LANE (gimple stmt ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+}
+
/* Routines to expand each internal function, indexed by function number.
Each routine has the prototype:
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 8900d90dc22..5427664b8e3 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -40,3 +40,6 @@ along with GCC; see the file COPYING3. If not see
DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF)
DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF)
+DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 93934e20de8..78dee15aad8 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -745,17 +745,26 @@ initialize_node_lattices (struct cgraph_node *node)
/* Return the result of a (possibly arithmetic) pass through jump function
JFUNC on the constant value INPUT. Return NULL_TREE if that cannot be
- determined or itself is considered an interprocedural invariant. */
+ determined or be considered an interprocedural invariant. */
static tree
ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
{
tree restype, res;
+ if (TREE_CODE (input) == TREE_BINFO)
+ {
+ if (ipa_get_jf_pass_through_type_preserved (jfunc))
+ {
+ gcc_checking_assert (ipa_get_jf_pass_through_operation (jfunc)
+ == NOP_EXPR);
+ return input;
+ }
+ return NULL_TREE;
+ }
+
if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
return input;
- else if (TREE_CODE (input) == TREE_BINFO)
- return NULL_TREE;
gcc_checking_assert (is_gimple_ip_invariant (input));
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
@@ -779,9 +788,13 @@ static tree
ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
{
if (TREE_CODE (input) == TREE_BINFO)
- return get_binfo_at_offset (input,
- ipa_get_jf_ancestor_offset (jfunc),
- ipa_get_jf_ancestor_type (jfunc));
+ {
+ if (!ipa_get_jf_ancestor_type_preserved (jfunc))
+ return NULL;
+ return get_binfo_at_offset (input,
+ ipa_get_jf_ancestor_offset (jfunc),
+ ipa_get_jf_ancestor_type (jfunc));
+ }
else if (TREE_CODE (input) == ADDR_EXPR)
{
tree t = TREE_OPERAND (input, 0);
@@ -1013,26 +1026,16 @@ propagate_vals_accross_pass_through (struct cgraph_edge *cs,
struct ipcp_value *src_val;
bool ret = false;
- if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
- for (src_val = src_lat->values; src_val; src_val = src_val->next)
- ret |= add_scalar_value_to_lattice (dest_lat, src_val->value, cs,
- src_val, src_idx);
/* Do not create new values when propagating within an SCC because if there
are arithmetic functions with circular dependencies, there is infinite
number of them and we would just make lattices bottom. */
- else if (edge_within_scc (cs))
+ if ((ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
+ and edge_within_scc (cs))
ret = set_lattice_contains_variable (dest_lat);
else
for (src_val = src_lat->values; src_val; src_val = src_val->next)
{
- tree cstval = src_val->value;
-
- if (TREE_CODE (cstval) == TREE_BINFO)
- {
- ret |= set_lattice_contains_variable (dest_lat);
- continue;
- }
- cstval = ipa_get_jf_pass_through_result (jfunc, cstval);
+ tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value);
if (cstval)
ret |= add_scalar_value_to_lattice (dest_lat, cstval, cs, src_val,
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 2cdf87519c5..11526957190 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -113,10 +113,12 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "ipa-inline.h"
#include "ipa-utils.h"
+#include "sreal.h"
/* Statistics we collect about inlining algorithm. */
static int overall_size;
static gcov_type max_count;
+static sreal max_count_real, max_relbenefit_real, half_int_min_real;
/* Return false when inlining edge E would lead to violating
limits on function unit growth or stack usage growth.
@@ -891,12 +893,26 @@ edge_badness (struct cgraph_edge *edge, bool dump)
else if (max_count)
{
+ sreal tmp, relbenefit_real, growth_real;
int relbenefit = relative_time_benefit (callee_info, edge, edge_time);
- badness =
- ((int)
- ((double) edge->count * INT_MIN / 2 / max_count / RELATIVE_TIME_BENEFIT_RANGE) *
- relbenefit) / growth;
-
+
+ sreal_init(&relbenefit_real, relbenefit, 0);
+ sreal_init(&growth_real, growth, 0);
+
+ /* relative_edge_count. */
+ sreal_init (&tmp, edge->count, 0);
+ sreal_div (&tmp, &tmp, &max_count_real);
+
+ /* relative_time_benefit. */
+ sreal_mul (&tmp, &tmp, &relbenefit_real);
+ sreal_div (&tmp, &tmp, &max_relbenefit_real);
+
+ /* growth_f_caller. */
+ sreal_mul (&tmp, &tmp, &half_int_min_real);
+ sreal_div (&tmp, &tmp, &growth_real);
+
+ badness = -1 * sreal_to_int (&tmp);
+
/* Be sure that insanity of the profile won't lead to increasing counts
in the scalling and thus to overflow in the computation above. */
gcc_assert (max_count >= edge->count);
@@ -1542,6 +1558,9 @@ inline_small_functions (void)
if (max_count < edge->count)
max_count = edge->count;
}
+ sreal_init (&max_count_real, max_count, 0);
+ sreal_init (&max_relbenefit_real, RELATIVE_TIME_BENEFIT_RANGE, 0);
+ sreal_init (&half_int_min_real, INT_MAX / 2, 0);
ipa_free_postorder_info ();
initialize_growth_caches ();
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 9074a63161e..ca133134d50 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -257,6 +257,8 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
}
if (jump_func->value.pass_through.agg_preserved)
fprintf (f, ", agg_preserved");
+ if (jump_func->value.pass_through.type_preserved)
+ fprintf (f, ", type_preserved");
fprintf (f, "\n");
}
else if (type == IPA_JF_ANCESTOR)
@@ -268,6 +270,8 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
print_generic_expr (f, jump_func->value.ancestor.type, 0);
if (jump_func->value.ancestor.agg_preserved)
fprintf (f, ", agg_preserved");
+ if (jump_func->value.ancestor.type_preserved)
+ fprintf (f, ", type_preserved");
fprintf (f, "\n");
}
@@ -373,6 +377,19 @@ ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
jfunc->value.known_type.component_type = component_type;
}
+/* Set JFUNC to be a copy of another jmp (to be used by jump function
+ combination code). The two functions will share their rdesc. */
+
+static void
+ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
+ struct ipa_jump_func *src)
+
+{
+ gcc_checking_assert (src->type == IPA_JF_CONST);
+ dst->type = IPA_JF_CONST;
+ dst->value.constant = src->value.constant;
+}
+
/* Set JFUNC to be a constant jmp function. */
static void
@@ -406,13 +423,14 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
/* Set JFUNC to be a simple pass-through jump function. */
static void
ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
- bool agg_preserved)
+ bool agg_preserved, bool type_preserved)
{
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.operand = NULL_TREE;
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = NOP_EXPR;
jfunc->value.pass_through.agg_preserved = agg_preserved;
+ jfunc->value.pass_through.type_preserved = type_preserved;
}
/* Set JFUNC to be an arithmetic pass through jump function. */
@@ -426,19 +444,22 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = operation;
jfunc->value.pass_through.agg_preserved = false;
+ jfunc->value.pass_through.type_preserved = false;
}
/* Set JFUNC to be an ancestor jump function. */
static void
ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
- tree type, int formal_id, bool agg_preserved)
+ tree type, int formal_id, bool agg_preserved,
+ bool type_preserved)
{
jfunc->type = IPA_JF_ANCESTOR;
jfunc->value.ancestor.formal_id = formal_id;
jfunc->value.ancestor.offset = offset;
jfunc->value.ancestor.type = type;
jfunc->value.ancestor.agg_preserved = agg_preserved;
+ jfunc->value.ancestor.type_preserved = type_preserved;
}
/* Extract the acual BINFO being described by JFUNC which must be a known type
@@ -1005,12 +1026,13 @@ compute_complex_assign_jump_func (struct ipa_node_params *info,
ipa_set_jf_arith_pass_through (jfunc, index, op2,
gimple_assign_rhs_code (stmt));
}
- else if (gimple_assign_single_p (stmt)
- && !detect_type_change_ssa (tc_ssa, call, jfunc))
+ else if (gimple_assign_single_p (stmt))
{
bool agg_p = parm_ref_data_pass_through_p (&parms_ainfo[index],
call, tc_ssa);
- ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
+ bool type_p = !detect_type_change_ssa (tc_ssa, call, jfunc);
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
+ ipa_set_jf_simple_pass_through (jfunc, index, agg_p, type_p);
}
return;
}
@@ -1033,13 +1055,16 @@ compute_complex_assign_jump_func (struct ipa_node_params *info,
|| offset < 0)
return;
- /* Dynamic types are changed only in constructors and destructors and */
+ /* Dynamic types are changed in constructors and destructors. */
index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
- if (index >= 0
- && !detect_type_change (op1, base, call, jfunc, offset))
- ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (op1), index,
- parm_ref_data_pass_through_p (&parms_ainfo[index],
- call, ssa));
+ if (index >= 0)
+ {
+ bool type_p = !detect_type_change (op1, base, call, jfunc, offset);
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
+ ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (op1), index,
+ parm_ref_data_pass_through_p (&parms_ainfo[index],
+ call, ssa), type_p);
+ }
}
/* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
@@ -1163,10 +1188,11 @@ compute_complex_ancestor_jump_func (struct ipa_node_params *info,
return;
}
- if (!detect_type_change (obj, expr, call, jfunc, offset))
+ bool type_p = !detect_type_change (obj, expr, call, jfunc, offset);
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (obj), index,
parm_ref_data_pass_through_p (&parms_ainfo[index],
- call, parm));
+ call, parm), type_p);
}
/* Given OP which is passed as an actual argument to a called function,
@@ -1507,7 +1533,7 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo,
for cycle. */
if (parm_preserved_before_stmt_p (&parms_ainfo[index], call, arg))
{
- ipa_set_jf_simple_pass_through (jfunc, index, false);
+ ipa_set_jf_simple_pass_through (jfunc, index, false, false);
continue;
}
}
@@ -1516,13 +1542,14 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo,
if (SSA_NAME_IS_DEFAULT_DEF (arg))
{
int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
- if (index >= 0
- && !detect_type_change_ssa (arg, call, jfunc))
+ if (index >= 0)
{
- bool agg_p;
+ bool agg_p, type_p;
agg_p = parm_ref_data_pass_through_p (&parms_ainfo[index],
call, arg);
- ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
+ type_p = !detect_type_change_ssa (arg, call, jfunc);
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
+ ipa_set_jf_simple_pass_through (jfunc, index, agg_p, type_p);
}
}
else
@@ -2130,6 +2157,12 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
HOST_WIDE_INT combined_offset;
tree combined_type;
+ if (!ipa_get_jf_ancestor_type_preserved (dst))
+ {
+ dst->type = IPA_JF_UNKNOWN;
+ return;
+ }
+
combined_offset = ipa_get_jf_known_type_offset (src)
+ ipa_get_jf_ancestor_offset (dst);
combined_type = ipa_get_jf_ancestor_type (dst);
@@ -2196,6 +2229,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
dst->value.ancestor.agg_preserved &=
src->value.pass_through.agg_preserved;
+ dst->value.ancestor.type_preserved &=
+ src->value.pass_through.type_preserved;
}
else if (src->type == IPA_JF_ANCESTOR)
{
@@ -2203,6 +2238,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
dst->value.ancestor.offset += src->value.ancestor.offset;
dst->value.ancestor.agg_preserved &=
src->value.ancestor.agg_preserved;
+ dst->value.ancestor.type_preserved &=
+ src->value.ancestor.type_preserved;
}
else
dst->type = IPA_JF_UNKNOWN;
@@ -2216,16 +2253,69 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
&& (dst->value.pass_through.formal_id
< ipa_get_cs_argument_count (top)))
{
- bool agg_p;
int dst_fid = dst->value.pass_through.formal_id;
src = ipa_get_ith_jump_func (top, dst_fid);
- agg_p = dst->value.pass_through.agg_preserved;
+ bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
- dst->type = src->type;
- dst->value = src->value;
+ switch (src->type)
+ {
+ case IPA_JF_UNKNOWN:
+ dst->type = IPA_JF_UNKNOWN;
+ break;
+ case IPA_JF_KNOWN_TYPE:
+ ipa_set_jf_known_type (dst,
+ ipa_get_jf_known_type_offset (src),
+ ipa_get_jf_known_type_base_type (src),
+ ipa_get_jf_known_type_base_type (src));
+ break;
+ case IPA_JF_CONST:
+ ipa_set_jf_cst_copy (dst, src);
+ break;
+
+ case IPA_JF_PASS_THROUGH:
+ {
+ int formal_id = ipa_get_jf_pass_through_formal_id (src);
+ enum tree_code operation;
+ operation = ipa_get_jf_pass_through_operation (src);
+
+ if (operation == NOP_EXPR)
+ {
+ bool agg_p, type_p;
+ agg_p = dst_agg_p
+ && ipa_get_jf_pass_through_agg_preserved (src);
+ type_p = ipa_get_jf_pass_through_type_preserved (src)
+ && ipa_get_jf_pass_through_type_preserved (dst);
+ ipa_set_jf_simple_pass_through (dst, formal_id,
+ agg_p, type_p);
+ }
+ else
+ {
+ tree operand = ipa_get_jf_pass_through_operand (src);
+ ipa_set_jf_arith_pass_through (dst, formal_id, operand,
+ operation);
+ }
+ break;
+ }
+ case IPA_JF_ANCESTOR:
+ {
+ bool agg_p, type_p;
+ agg_p = dst_agg_p
+ && ipa_get_jf_ancestor_agg_preserved (src);
+ type_p = ipa_get_jf_ancestor_type_preserved (src)
+ && ipa_get_jf_pass_through_type_preserved (dst);
+ ipa_set_ancestor_jf (dst,
+ ipa_get_jf_ancestor_offset (src),
+ ipa_get_jf_ancestor_type (src),
+ ipa_get_jf_ancestor_formal_id (src),
+ agg_p, type_p);
+ break;
+ }
+ default:
+ gcc_unreachable ();
+ }
if (src->agg.items
- && (agg_p || !src->agg.by_ref))
+ && (dst_agg_p || !src->agg.by_ref))
{
/* Currently we do not produce clobber aggregate jump
functions, replace with merging when we do. */
@@ -2234,14 +2324,6 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
dst->agg.by_ref = src->agg.by_ref;
dst->agg.items = vec_safe_copy (src->agg.items);
}
-
- if (!agg_p)
- {
- if (dst->type == IPA_JF_PASS_THROUGH)
- dst->value.pass_through.agg_preserved = false;
- else if (dst->type == IPA_JF_ANCESTOR)
- dst->value.ancestor.agg_preserved = false;
- }
}
else
dst->type = IPA_JF_UNKNOWN;
@@ -3703,6 +3785,7 @@ ipa_write_jump_function (struct output_block *ob,
streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
+ bp_pack_value (&bp, jump_func->value.pass_through.type_preserved, 1);
streamer_write_bitpack (&bp);
}
else
@@ -3717,6 +3800,7 @@ ipa_write_jump_function (struct output_block *ob,
streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
+ bp_pack_value (&bp, jump_func->value.ancestor.type_preserved, 1);
streamer_write_bitpack (&bp);
break;
}
@@ -3774,7 +3858,9 @@ ipa_read_jump_function (struct lto_input_block *ib,
int formal_id = streamer_read_uhwi (ib);
struct bitpack_d bp = streamer_read_bitpack (ib);
bool agg_preserved = bp_unpack_value (&bp, 1);
- ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
+ bool type_preserved = bp_unpack_value (&bp, 1);
+ ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
+ type_preserved);
}
else
{
@@ -3791,8 +3877,10 @@ ipa_read_jump_function (struct lto_input_block *ib,
int formal_id = streamer_read_uhwi (ib);
struct bitpack_d bp = streamer_read_bitpack (ib);
bool agg_preserved = bp_unpack_value (&bp, 1);
+ bool type_preserved = bp_unpack_value (&bp, 1);
- ipa_set_ancestor_jf (jump_func, offset, type, formal_id, agg_preserved);
+ ipa_set_ancestor_jf (jump_func, offset, type, formal_id, agg_preserved,
+ type_preserved);
break;
}
}
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 2ccac2f3ede..48634d2e172 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -117,7 +117,12 @@ struct GTY(()) ipa_pass_through_data
aggregate part of the jump function (see description of
ipa_agg_jump_function). The flag is used only when the operation is
NOP_EXPR. */
- bool agg_preserved;
+ unsigned agg_preserved : 1;
+
+ /* When set to true, we guarantee that, if there is a C++ object pointed to
+ by this object, it does not undergo dynamic type change in the course of
+ functions decribed by this jump function. */
+ unsigned type_preserved : 1;
};
/* Structure holding data required to describe an ancestor pass-through
@@ -132,7 +137,11 @@ struct GTY(()) ipa_ancestor_jf_data
/* Number of the caller's formal parameter being passed. */
int formal_id;
/* Flag with the same meaning like agg_preserve in ipa_pass_through_data. */
- bool agg_preserved;
+ unsigned agg_preserved : 1;
+ /* When set to true, we guarantee that, if there is a C++ object pointed to
+ by this object, it does not undergo dynamic type change in the course of
+ functions decribed by this jump function. */
+ unsigned type_preserved : 1;
};
/* An element in an aggegate part of a jump function describing a known value
@@ -264,7 +273,7 @@ ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
return jfunc->value.pass_through.operation;
}
-/* Return the agg_preserved flag of a pass through jump functin JFUNC. */
+/* Return the agg_preserved flag of a pass through jump function JFUNC. */
static inline bool
ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
@@ -273,6 +282,15 @@ ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
return jfunc->value.pass_through.agg_preserved;
}
+/* Return the type_preserved flag of a pass through jump function JFUNC. */
+
+static inline bool
+ipa_get_jf_pass_through_type_preserved (struct ipa_jump_func *jfunc)
+{
+ gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
+ return jfunc->value.pass_through.type_preserved;
+}
+
/* Return the offset of an ancestor jump function JFUNC. */
static inline HOST_WIDE_INT
@@ -301,7 +319,7 @@ ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
return jfunc->value.ancestor.formal_id;
}
-/* Return the agg_preserved flag of an ancestor jump functin JFUNC. */
+/* Return the agg_preserved flag of an ancestor jump function JFUNC. */
static inline bool
ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
@@ -310,6 +328,15 @@ ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
return jfunc->value.ancestor.agg_preserved;
}
+/* Return the type_preserved flag of an ancestor jump function JFUNC. */
+
+static inline bool
+ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
+{
+ gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
+ return jfunc->value.ancestor.type_preserved;
+}
+
/* Summary describing a single formal parameter. */
struct ipa_param_descriptor
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index fa0260175d8..ad26f3da174 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -225,7 +225,7 @@ report_unroll_peel (struct loop *loop, location_t locus)
&& !loop->lpt_decision.times)
{
dump_printf_loc (report_flags, locus,
- "Turned loop into non-loop; it never loops.\n");
+ "loop turned into non-loop; it never loops.\n");
return;
}
@@ -236,13 +236,16 @@ report_unroll_peel (struct loop *loop, location_t locus)
else if (loop->header->count)
niters = expected_loop_iterations (loop);
- dump_printf_loc (report_flags, locus,
- "%s loop %d times",
- (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
- ? "Completely unroll"
- : (loop->lpt_decision.decision == LPT_PEEL_SIMPLE
- ? "Peel" : "Unroll")),
- loop->lpt_decision.times);
+ if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
+ dump_printf_loc (report_flags, locus,
+ "loop with %d iterations completely unrolled",
+ loop->lpt_decision.times + 1);
+ else
+ dump_printf_loc (report_flags, locus,
+ "loop %s %d times",
+ (loop->lpt_decision.decision == LPT_PEEL_SIMPLE
+ ? "peeled" : "unrolled"),
+ loop->lpt_decision.times);
if (profile_info)
dump_printf (report_flags,
" (header execution count %d",
diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c
index 0ef421f6167..5821030d4cf 100644
--- a/gcc/lto-section-in.c
+++ b/gcc/lto-section-in.c
@@ -414,6 +414,41 @@ lto_get_function_in_decl_state (struct lto_file_decl_data *file_data,
return slot? ((struct lto_in_decl_state*) *slot) : NULL;
}
+/* Free decl_states. */
+
+void
+lto_free_function_in_decl_state (struct lto_in_decl_state *state)
+{
+ int i;
+ for (i = 0; i < LTO_N_DECL_STREAMS; i++)
+ ggc_free (state->streams[i].trees);
+ ggc_free (state);
+}
+
+/* Free decl_states associated with NODE. This makes it possible to furhter
+ release trees needed by the NODE's body. */
+
+void
+lto_free_function_in_decl_state_for_node (symtab_node node)
+{
+ struct lto_in_decl_state temp;
+ void **slot;
+
+ if (!node->symbol.lto_file_data)
+ return;
+
+ temp.fn_decl = node->symbol.decl;
+ slot = htab_find_slot (node->symbol.lto_file_data->function_decl_states,
+ &temp, NO_INSERT);
+ if (slot && *slot)
+ {
+ lto_free_function_in_decl_state ((struct lto_in_decl_state*) *slot);
+ htab_clear_slot (node->symbol.lto_file_data->function_decl_states,
+ slot);
+ }
+ node->symbol.lto_file_data = NULL;
+}
+
/* Report read pass end of the section. */
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index ea0ff177c47..dfcd1357179 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -642,9 +642,8 @@ DFS_write_tree_body (struct output_block *ob,
FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (expr), i, t)
DFS_follow_tree_edge (t);
- DFS_follow_tree_edge (BINFO_INHERITANCE_CHAIN (expr));
- DFS_follow_tree_edge (BINFO_SUBVTT_INDEX (expr));
- DFS_follow_tree_edge (BINFO_VPTR_INDEX (expr));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
@@ -748,7 +747,6 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
v = iterative_hash_host_wide_int (DECL_ALIGN (t), v);
if (code == LABEL_DECL)
{
- v = iterative_hash_host_wide_int (DECL_ERROR_ISSUED (t), v);
v = iterative_hash_host_wide_int (EH_LANDING_PAD_NR (t), v);
v = iterative_hash_host_wide_int (LABEL_DECL_UID (t), v);
}
@@ -781,23 +779,27 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
{
- v = iterative_hash_host_wide_int (DECL_DEFER_OUTPUT (t)
- | (DECL_COMMON (t) << 1)
- | (DECL_DLLIMPORT_P (t) << 2)
- | (DECL_WEAK (t) << 3)
- | (DECL_SEEN_IN_BIND_EXPR_P (t) << 4)
- | (DECL_COMDAT (t) << 5)
+ v = iterative_hash_host_wide_int ((DECL_COMMON (t))
+ | (DECL_DLLIMPORT_P (t) << 1)
+ | (DECL_WEAK (t) << 2)
+ | (DECL_SEEN_IN_BIND_EXPR_P (t) << 3)
+ | (DECL_COMDAT (t) << 4)
| (DECL_VISIBILITY_SPECIFIED (t) << 6),
v);
v = iterative_hash_host_wide_int (DECL_VISIBILITY (t), v);
if (code == VAR_DECL)
{
+ /* DECL_IN_TEXT_SECTION is set during final asm output only. */
v = iterative_hash_host_wide_int (DECL_HARD_REGISTER (t)
- | (DECL_IN_TEXT_SECTION (t) << 1)
- | (DECL_IN_CONSTANT_POOL (t) << 2),
+ | (DECL_IN_CONSTANT_POOL (t) << 1),
v);
v = iterative_hash_host_wide_int (DECL_TLS_MODEL (t), v);
}
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ v = iterative_hash_host_wide_int (DECL_FINAL_P (t)
+ | (DECL_CXX_CONSTRUCTOR_P (t) << 1)
+ | (DECL_CXX_DESTRUCTOR_P (t) << 2),
+ v);
if (VAR_OR_FUNCTION_DECL_P (t))
v = iterative_hash_host_wide_int (DECL_INIT_PRIORITY (t), v);
}
@@ -838,7 +840,10 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
| (TYPE_USER_ALIGN (t) << 5)
| (TYPE_READONLY (t) << 6), v);
if (RECORD_OR_UNION_TYPE_P (t))
- v = iterative_hash_host_wide_int (TYPE_TRANSPARENT_AGGR (t), v);
+ {
+ v = iterative_hash_host_wide_int (TYPE_TRANSPARENT_AGGR (t)
+ | (TYPE_FINAL_P (t) << 1), v);
+ }
else if (code == ARRAY_TYPE)
v = iterative_hash_host_wide_int (TYPE_NONALIASED_COMPONENT (t), v);
v = iterative_hash_host_wide_int (TYPE_PRECISION (t), v);
@@ -1021,9 +1026,8 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
visit (BINFO_VPTR_FIELD (t));
FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (t), i, b)
visit (b);
- visit (BINFO_INHERITANCE_CHAIN (t));
- visit (BINFO_SUBVTT_INDEX (t));
- visit (BINFO_VPTR_INDEX (t));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index e7c89f16162..663ab24aa05 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -774,6 +774,8 @@ extern hashval_t lto_hash_in_decl_state (const void *);
extern int lto_eq_in_decl_state (const void *, const void *);
extern struct lto_in_decl_state *lto_get_function_in_decl_state (
struct lto_file_decl_data *, tree);
+extern void lto_free_function_in_decl_state (struct lto_in_decl_state *);
+extern void lto_free_function_in_decl_state_for_node (symtab_node);
extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN;
extern void lto_value_range_error (const char *,
HOST_WIDE_INT, HOST_WIDE_INT,
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index 9bebd09c832..7c2add7232a 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -80,6 +80,8 @@ lto_cgraph_replace_node (struct cgraph_node *node,
/* Redirect incomming references. */
ipa_clone_referring ((symtab_node)prevailing_node, &node->symbol.ref_list);
+ lto_free_function_in_decl_state_for_node ((symtab_node)node);
+
if (node->symbol.decl != prevailing_node->symbol.decl)
cgraph_release_function_body (node);
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index cb10a4bf8c8..965a78ce5c8 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,25 @@
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (read_cgraph_and_symbols): Free decl states.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (compare_tree_sccs_1): Compare DECL_FINAL_P,
+ DECL_CXX_CONSTRUCTOR_P, DECL_CXX_DESTRUCTOR_P and
+ TYPE_FINAL_P.
+
+2013-08-28 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (compare_tree_sccs_1): Drop DECL_ERROR_ISSUED,
+ DECL_DEFER_OUTPUT and DECL_IN_TEXT_SECTION.
+ (unify_scc): Do checking assert.
+
+2013-08-06 Jan Hubicka <jh@suse.cz>
+ Martin Liska <marxin.liska@gmail.com>
+
+ * lto-partition.c (lto_balanced_map): Always base order on
+ source file order.
+
2013-08-06 Jan Hubicka <jh@suse.cz>
* lto.c (lto_materialize_function): Do not read body anymore.
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 879218ce2fa..e05f805fea4 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -449,11 +449,9 @@ lto_balanced_map (void)
{
int n_nodes = 0;
int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0;
- struct cgraph_node **postorder =
- XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
struct cgraph_node **order = XNEWVEC (struct cgraph_node *, cgraph_max_uid);
struct varpool_node **varpool_order = NULL;
- int i, postorder_len;
+ int i;
struct cgraph_node *node;
int total_size = 0, best_total_size = 0;
int partition_size;
@@ -468,24 +466,20 @@ lto_balanced_map (void)
FOR_EACH_VARIABLE (vnode)
gcc_assert (!vnode->symbol.aux);
- /* Until we have better ordering facility, use toplogical order.
- Include only nodes we will partition and compute estimate of program
- size. Note that since nodes that are not partitioned might be put into
- multiple partitions, this is just an estimate of real size. This is why
- we keep partition_size updated after every partition is finalized. */
- postorder_len = ipa_reverse_postorder (postorder);
- for (i = 0; i < postorder_len; i++)
- {
- node = postorder[i];
- if (get_symbol_class ((symtab_node) node) == SYMBOL_PARTITION)
- {
- order[n_nodes++] = node;
- total_size += inline_summary (node)->size;
- }
- }
- free (postorder);
+ FOR_EACH_DEFINED_FUNCTION (node)
+ if (get_symbol_class ((symtab_node) node) == SYMBOL_PARTITION)
+ {
+ order[n_nodes++] = node;
+ total_size += inline_summary (node)->size;
+ }
+ /* Streaming works best when the source units do not cross partition
+ boundaries much. This is because importing function from a source
+ 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);
if (!flag_toplevel_reorder)
{
qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index c854589c673..cc0ed69a5f2 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1431,9 +1431,8 @@ maybe_remember_with_vars_binfo (tree t)
n = vec_safe_length (BINFO_BASE_ACCESSES (t));
for (i = 0; i < n; i++)
MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_ACCESS (t, i));
- MAYBE_REMEMBER_WITH_VARS (BINFO_INHERITANCE_CHAIN (t));
- MAYBE_REMEMBER_WITH_VARS (BINFO_SUBVTT_INDEX (t));
- MAYBE_REMEMBER_WITH_VARS (BINFO_VPTR_INDEX (t));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
n = BINFO_N_BASE_BINFOS (t);
for (i = 0; i < n; i++)
MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_BINFO (t, i));
@@ -1823,7 +1822,6 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_ALIGN);
if (code == LABEL_DECL)
{
- compare_values (DECL_ERROR_ISSUED);
compare_values (EH_LANDING_PAD_NR);
compare_values (LABEL_DECL_UID);
}
@@ -1854,7 +1852,6 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
{
- compare_values (DECL_DEFER_OUTPUT);
compare_values (DECL_COMMON);
compare_values (DECL_DLLIMPORT_P);
compare_values (DECL_WEAK);
@@ -1865,7 +1862,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
if (code == VAR_DECL)
{
compare_values (DECL_HARD_REGISTER);
- compare_values (DECL_IN_TEXT_SECTION);
+ /* DECL_IN_TEXT_SECTION is set during final asm output only. */
compare_values (DECL_IN_CONSTANT_POOL);
compare_values (DECL_TLS_MODEL);
}
@@ -1892,6 +1889,9 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_DISREGARD_INLINE_LIMITS);
compare_values (DECL_PURE_P);
compare_values (DECL_LOOPING_CONST_OR_PURE_P);
+ compare_values (DECL_FINAL_P);
+ compare_values (DECL_CXX_CONSTRUCTOR_P);
+ compare_values (DECL_CXX_DESTRUCTOR_P);
if (DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN)
compare_values (DECL_FUNCTION_CODE);
if (DECL_STATIC_DESTRUCTOR (t1))
@@ -1905,7 +1905,10 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (TYPE_NO_FORCE_BLK);
compare_values (TYPE_NEEDS_CONSTRUCTING);
if (RECORD_OR_UNION_TYPE_P (t1))
- compare_values (TYPE_TRANSPARENT_AGGR);
+ {
+ compare_values (TYPE_TRANSPARENT_AGGR);
+ compare_values (TYPE_FINAL_P);
+ }
else if (code == ARRAY_TYPE)
compare_values (TYPE_NONALIASED_COMPONENT);
compare_values (TYPE_PACKED);
@@ -2167,12 +2170,8 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_tree_edges (BINFO_OFFSET (t1), BINFO_OFFSET (t2));
compare_tree_edges (BINFO_VTABLE (t1), BINFO_VTABLE (t2));
compare_tree_edges (BINFO_VPTR_FIELD (t1), BINFO_VPTR_FIELD (t2));
- compare_tree_edges (BINFO_INHERITANCE_CHAIN (t1),
- BINFO_INHERITANCE_CHAIN (t2));
- compare_tree_edges (BINFO_SUBVTT_INDEX (t1),
- BINFO_SUBVTT_INDEX (t2));
- compare_tree_edges (BINFO_VPTR_INDEX (t1),
- BINFO_VPTR_INDEX (t2));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
@@ -2284,7 +2283,7 @@ unify_scc (struct streamer_tree_cache_d *cache, unsigned from,
for (unsigned i = 0; i < scc->len; ++i)
{
TREE_VISITED (scc->entries[i]) = 1;
- gcc_assert (!TREE_ASM_WRITTEN (scc->entries[i]));
+ gcc_checking_assert (!TREE_ASM_WRITTEN (scc->entries[i]));
}
tree *map = XALLOCAVEC (tree, 2 * len);
@@ -3503,6 +3502,9 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
gcc_assert (all_file_decl_data[i]->symtab_node_encoder);
lto_symtab_encoder_delete (all_file_decl_data[i]->symtab_node_encoder);
all_file_decl_data[i]->symtab_node_encoder = NULL;
+ lto_free_function_in_decl_state (all_file_decl_data[i]->global_decl_state);
+ all_file_decl_data[i]->global_decl_state = NULL;
+ all_file_decl_data[i]->current_decl_state = NULL;
}
/* Finally merge the cgraph according to the decl merging decisions. */
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e5eaddb51fc..6da219e6869 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "splay-tree.h"
#include "optabs.h"
#include "cfgloop.h"
+#include "target.h"
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
@@ -222,6 +223,7 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
int i;
struct omp_for_data_loop dummy_loop;
location_t loc = gimple_location (for_stmt);
+ bool simd = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD;
fd->for_stmt = for_stmt;
fd->pre = NULL;
@@ -349,7 +351,18 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
gcc_unreachable ();
}
- if (iter_type != long_long_unsigned_type_node)
+ if (simd)
+ {
+ if (fd->collapse == 1)
+ iter_type = TREE_TYPE (loop->v);
+ else if (i == 0
+ || TYPE_PRECISION (iter_type)
+ < TYPE_PRECISION (TREE_TYPE (loop->v)))
+ iter_type
+ = build_nonstandard_integer_type
+ (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
+ }
+ else if (iter_type != long_long_unsigned_type_node)
{
if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
iter_type = long_long_unsigned_type_node;
@@ -445,7 +458,8 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
}
}
- if (count)
+ if (count
+ && !simd)
{
if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
iter_type = long_long_unsigned_type_node;
@@ -836,6 +850,7 @@ copy_var_decl (tree var, tree name, tree type)
DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
DECL_CONTEXT (copy) = DECL_CONTEXT (var);
+ TREE_NO_WARNING (copy) = TREE_NO_WARNING (var);
TREE_USED (copy) = 1;
DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
@@ -918,6 +933,19 @@ build_outer_var_ref (tree var, omp_context *ctx)
bool by_ref = use_pointer_for_field (var, NULL);
x = build_receiver_ref (var, by_ref, ctx);
}
+ else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ {
+ /* #pragma omp simd isn't a worksharing construct, and can reference even
+ private vars in its linear etc. clauses. */
+ x = NULL_TREE;
+ if (ctx->outer && is_taskreg_ctx (ctx))
+ x = lookup_decl (var, ctx->outer);
+ else if (ctx->outer)
+ x = maybe_lookup_decl (var, ctx->outer);
+ if (x == NULL_TREE)
+ x = var;
+ }
else if (ctx->outer)
x = lookup_decl (var, ctx->outer);
else if (is_reference (var))
@@ -1423,6 +1451,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_LINEAR:
decl = OMP_CLAUSE_DECL (c);
do_private:
if (is_variable_sized (decl))
@@ -1474,6 +1503,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
default:
@@ -1497,6 +1527,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_LINEAR:
decl = OMP_CLAUSE_DECL (c);
if (is_variable_sized (decl))
install_var_local (decl, ctx);
@@ -1526,6 +1557,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
default:
@@ -1631,7 +1663,6 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
pop_cfun ();
}
-
/* Scan an OpenMP parallel directive. */
static void
@@ -1831,9 +1862,22 @@ scan_omp_single (gimple stmt, omp_context *outer_ctx)
static bool
check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
{
+ if (ctx != NULL)
+ {
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ {
+ error_at (gimple_location (stmt),
+ "OpenMP constructs may not be nested inside simd region");
+ return false;
+ }
+ }
switch (gimple_code (stmt))
{
case GIMPLE_OMP_FOR:
+ if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
+ return true;
+ /* FALLTHRU */
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SINGLE:
case GIMPLE_CALL:
@@ -2254,6 +2298,73 @@ omp_reduction_init (tree clause, tree type)
}
}
+/* Return maximum possible vectorization factor for the target. */
+
+static int
+omp_max_vf (void)
+{
+ if (!optimize
+ || optimize_debug
+ || (!flag_tree_vectorize
+ && global_options_set.x_flag_tree_vectorize))
+ return 1;
+
+ int vs = targetm.vectorize.autovectorize_vector_sizes ();
+ if (vs)
+ {
+ vs = 1 << floor_log2 (vs);
+ return vs;
+ }
+ enum machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
+ if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
+ return GET_MODE_NUNITS (vqimode);
+ return 1;
+}
+
+/* Helper function of lower_rec_input_clauses, used for #pragma omp simd
+ privatization. */
+
+static bool
+lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
+ tree &idx, tree &lane, tree &ivar, tree &lvar)
+{
+ if (max_vf == 0)
+ {
+ max_vf = omp_max_vf ();
+ if (max_vf > 1)
+ {
+ tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
+ OMP_CLAUSE_SAFELEN);
+ if (c
+ && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c), max_vf) == -1)
+ max_vf = tree_low_cst (OMP_CLAUSE_SAFELEN_EXPR (c), 0);
+ }
+ if (max_vf > 1)
+ {
+ idx = create_tmp_var (unsigned_type_node, NULL);
+ lane = create_tmp_var (unsigned_type_node, NULL);
+ }
+ }
+ if (max_vf == 1)
+ return false;
+
+ tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
+ tree avar = create_tmp_var_raw (atype, NULL);
+ if (TREE_ADDRESSABLE (new_var))
+ TREE_ADDRESSABLE (avar) = 1;
+ DECL_ATTRIBUTES (avar)
+ = tree_cons (get_identifier ("omp simd array"), NULL,
+ DECL_ATTRIBUTES (avar));
+ gimple_add_tmp_var (avar);
+ ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
+ NULL_TREE, NULL_TREE);
+ lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
+ NULL_TREE, NULL_TREE);
+ SET_DECL_VALUE_EXPR (new_var, lvar);
+ DECL_HAS_VALUE_EXPR_P (new_var) = 1;
+ return true;
+}
+
/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
from the receiver (aka child) side and initializers for REFERENCE_TYPE
private variables. Initialization statements go in ILIST, while calls
@@ -2267,9 +2378,38 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
bool copyin_by_ref = false;
bool lastprivate_firstprivate = false;
int pass;
+ bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
+ int max_vf = 0;
+ tree lane = NULL_TREE, idx = NULL_TREE;
+ tree ivar = NULL_TREE, lvar = NULL_TREE;
+ gimple_seq llist[2] = { NULL, NULL };
copyin_seq = NULL;
+ /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
+ with data sharing clauses referencing variable sized vars. That
+ is unnecessarily hard to support and very unlikely to result in
+ vectorized code anyway. */
+ if (is_simd)
+ for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
+ max_vf = 1;
+ /* FALLTHRU */
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LASTPRIVATE:
+ case OMP_CLAUSE_LINEAR:
+ if (is_variable_sized (OMP_CLAUSE_DECL (c)))
+ max_vf = 1;
+ break;
+ default:
+ continue;
+ }
+
/* Do all the fixed sized types in the first pass, and the variable sized
types in the second pass. This makes sure that the scalar arguments to
the variable sized types are processed before we use them in the
@@ -2299,6 +2439,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_REDUCTION:
break;
+ case OMP_CLAUSE_LINEAR:
+ break;
case OMP_CLAUSE_LASTPRIVATE:
if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
{
@@ -2443,7 +2585,36 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
else
x = NULL;
+ do_private:
x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
+ if (is_simd)
+ {
+ tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
+ if ((TREE_ADDRESSABLE (new_var) || x || y
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
+ idx, lane, ivar, lvar))
+ {
+ if (x)
+ x = lang_hooks.decls.omp_clause_default_ctor
+ (c, unshare_expr (ivar), x);
+ if (x)
+ gimplify_and_add (x, &llist[0]);
+ if (y)
+ {
+ y = lang_hooks.decls.omp_clause_dtor (c, ivar);
+ if (y)
+ {
+ gimple_seq tseq = NULL;
+
+ dtor = y;
+ gimplify_stmt (&dtor, &tseq);
+ gimple_seq_add_seq (&llist[1], tseq);
+ }
+ }
+ break;
+ }
+ }
if (x)
gimplify_and_add (x, ilist);
/* FALLTHRU */
@@ -2460,6 +2631,15 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
break;
+ case OMP_CLAUSE_LINEAR:
+ if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
+ goto do_firstprivate;
+ if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+ x = NULL;
+ else
+ x = build_outer_var_ref (var, ctx);
+ goto do_private;
+
case OMP_CLAUSE_FIRSTPRIVATE:
if (is_task_ctx (ctx))
{
@@ -2475,11 +2655,56 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
goto do_dtor;
}
}
+ do_firstprivate:
x = build_outer_var_ref (var, ctx);
+ if (is_simd)
+ {
+ if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
+ || TREE_ADDRESSABLE (new_var))
+ && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
+ idx, lane, ivar, lvar))
+ {
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
+ {
+ tree iv = create_tmp_var (TREE_TYPE (new_var), NULL);
+ x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
+ gimplify_and_add (x, ilist);
+ gimple_stmt_iterator gsi
+ = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
+ gimple g
+ = gimple_build_assign (unshare_expr (lvar), iv);
+ gsi_insert_before_without_update (&gsi, g,
+ GSI_SAME_STMT);
+ tree stept = POINTER_TYPE_P (TREE_TYPE (x))
+ ? sizetype : TREE_TYPE (x);
+ tree t = fold_convert (stept,
+ OMP_CLAUSE_LINEAR_STEP (c));
+ enum tree_code code = PLUS_EXPR;
+ if (POINTER_TYPE_P (TREE_TYPE (new_var)))
+ code = POINTER_PLUS_EXPR;
+ g = gimple_build_assign_with_ops (code, iv, iv, t);
+ gsi_insert_before_without_update (&gsi, g,
+ GSI_SAME_STMT);
+ break;
+ }
+ x = lang_hooks.decls.omp_clause_copy_ctor
+ (c, unshare_expr (ivar), x);
+ gimplify_and_add (x, &llist[0]);
+ x = lang_hooks.decls.omp_clause_dtor (c, ivar);
+ if (x)
+ {
+ gimple_seq tseq = NULL;
+
+ dtor = x;
+ gimplify_stmt (&dtor, &tseq);
+ gimple_seq_add_seq (&llist[1], tseq);
+ }
+ break;
+ }
+ }
x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
gimplify_and_add (x, ilist);
goto do_dtor;
- break;
case OMP_CLAUSE_COPYIN:
by_ref = use_pointer_for_field (var, NULL);
@@ -2495,6 +2720,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
x = build_outer_var_ref (var, ctx);
+ /* FIXME: Not handled yet. */
+ gcc_assert (!is_simd);
if (is_reference (var))
x = build_fold_addr_expr_loc (clause_loc, x);
SET_DECL_VALUE_EXPR (placeholder, x);
@@ -2509,7 +2736,31 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
{
x = omp_reduction_init (c, TREE_TYPE (new_var));
gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
- gimplify_assign (new_var, x, ilist);
+ if (is_simd
+ && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
+ idx, lane, ivar, lvar))
+ {
+ enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
+ tree ref = build_outer_var_ref (var, ctx);
+
+ gimplify_assign (unshare_expr (ivar), x, &llist[0]);
+
+ /* reduction(-:var) sums up the partial results, so it
+ acts identically to reduction(+:var). */
+ if (code == MINUS_EXPR)
+ code = PLUS_EXPR;
+
+ x = build2 (code, TREE_TYPE (ref), ref, ivar);
+ ref = build_outer_var_ref (var, ctx);
+ gimplify_assign (ref, x, &llist[1]);
+ }
+ else
+ {
+ gimplify_assign (new_var, x, ilist);
+ if (is_simd)
+ gimplify_assign (build_outer_var_ref (var, ctx),
+ new_var, dlist);
+ }
}
break;
@@ -2519,6 +2770,49 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
}
+ if (lane)
+ {
+ tree uid = create_tmp_var (ptr_type_node, "simduid");
+ gimple g
+ = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
+ gimple_call_set_lhs (g, lane);
+ gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
+ gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
+ c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
+ OMP_CLAUSE__SIMDUID__DECL (c) = uid;
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
+ gimple_omp_for_set_clauses (ctx->stmt, c);
+ g = gimple_build_assign_with_ops (INTEGER_CST, lane,
+ build_int_cst (unsigned_type_node, 0),
+ NULL_TREE);
+ gimple_seq_add_stmt (ilist, g);
+ for (int i = 0; i < 2; i++)
+ if (llist[i])
+ {
+ tree vf = create_tmp_var (unsigned_type_node, NULL);
+ g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
+ gimple_call_set_lhs (g, vf);
+ gimple_seq *seq = i == 0 ? ilist : dlist;
+ gimple_seq_add_stmt (seq, g);
+ tree t = build_int_cst (unsigned_type_node, 0);
+ g = gimple_build_assign_with_ops (INTEGER_CST, idx, t, NULL_TREE);
+ gimple_seq_add_stmt (seq, g);
+ tree body = create_artificial_label (UNKNOWN_LOCATION);
+ tree header = create_artificial_label (UNKNOWN_LOCATION);
+ tree end = create_artificial_label (UNKNOWN_LOCATION);
+ gimple_seq_add_stmt (seq, gimple_build_goto (header));
+ gimple_seq_add_stmt (seq, gimple_build_label (body));
+ gimple_seq_add_seq (seq, llist[i]);
+ t = build_int_cst (unsigned_type_node, 1);
+ g = gimple_build_assign_with_ops (PLUS_EXPR, idx, idx, t);
+ gimple_seq_add_stmt (seq, g);
+ gimple_seq_add_stmt (seq, gimple_build_label (header));
+ g = gimple_build_cond (LT_EXPR, idx, vf, body, end);
+ gimple_seq_add_stmt (seq, g);
+ gimple_seq_add_stmt (seq, gimple_build_label (end));
+ }
+ }
+
/* The copyin sequence is not to be executed by the main thread, since
that would result in self-copies. Perhaps not visible to scalars,
but it certainly is to C++ operator=. */
@@ -2538,7 +2832,31 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
lastprivate clauses we need to ensure the lastprivate copying
happens after firstprivate copying in all threads. */
if (copyin_by_ref || lastprivate_firstprivate)
- gimplify_and_add (build_omp_barrier (), ilist);
+ {
+ /* Don't add any barrier for #pragma omp simd or
+ #pragma omp distribute. */
+ if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
+ || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
+ gimplify_and_add (build_omp_barrier (), ilist);
+ }
+
+ /* If max_vf is non-zero, then we can use only a vectorization factor
+ up to the max_vf we chose. So stick it into the safelen clause. */
+ if (max_vf)
+ {
+ tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
+ OMP_CLAUSE_SAFELEN);
+ if (c == NULL_TREE
+ || compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
+ max_vf) == 1)
+ {
+ c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
+ OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
+ max_vf);
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
+ gimple_omp_for_set_clauses (ctx->stmt, c);
+ }
+ }
}
@@ -2550,11 +2868,16 @@ static void
lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
omp_context *ctx)
{
- tree x, c, label = NULL;
+ tree x, c, label = NULL, orig_clauses = clauses;
bool par_clauses = false;
+ tree simduid = NULL, lastlane = NULL;
- /* Early exit if there are no lastprivate clauses. */
- clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
+ /* Early exit if there are no lastprivate or linear clauses. */
+ for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
+ if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
+ || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
+ && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
+ break;
if (clauses == NULL)
{
/* If this was a workshare clause, see if it had been combined
@@ -2591,23 +2914,59 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
}
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ {
+ simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
+ if (simduid)
+ simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
+ }
+
for (c = clauses; c ;)
{
tree var, new_var;
location_t clause_loc = OMP_CLAUSE_LOCATION (c);
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
{
var = OMP_CLAUSE_DECL (c);
new_var = lookup_decl (var, ctx);
- if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
+ if (simduid && DECL_HAS_VALUE_EXPR_P (new_var))
+ {
+ tree val = DECL_VALUE_EXPR (new_var);
+ if (TREE_CODE (val) == ARRAY_REF
+ && VAR_P (TREE_OPERAND (val, 0))
+ && lookup_attribute ("omp simd array",
+ DECL_ATTRIBUTES (TREE_OPERAND (val,
+ 0))))
+ {
+ if (lastlane == NULL)
+ {
+ lastlane = create_tmp_var (unsigned_type_node, NULL);
+ gimple g
+ = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
+ 2, simduid,
+ TREE_OPERAND (val, 1));
+ gimple_call_set_lhs (g, lastlane);
+ gimple_seq_add_stmt (stmt_list, g);
+ }
+ new_var = build4 (ARRAY_REF, TREE_TYPE (val),
+ TREE_OPERAND (val, 0), lastlane,
+ NULL_TREE, NULL_TREE);
+ }
+ }
+
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
{
lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
gimple_seq_add_seq (stmt_list,
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
+ OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
}
- OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
x = build_outer_var_ref (var, ctx);
if (is_reference (var))
@@ -2649,6 +3008,11 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
tree x, c;
int count = 0;
+ /* SIMD reductions are handled in lower_rec_input_clauses. */
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ return;
+
/* First see if there is exactly one reduction clause. Use OMP_ATOMIC
update in that case, otherwise use a lock. */
for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
@@ -3411,6 +3775,24 @@ expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
return NULL_TREE;
}
+/* Prepend TO = FROM assignment before *GSI_P. */
+
+static void
+expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from)
+{
+ bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
+ from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
+ true, GSI_SAME_STMT);
+ gimple stmt = gimple_build_assign (to, from);
+ gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
+ if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
+}
+
/* Expand the OpenMP parallel or task directive starting at REGION. */
static void
@@ -3654,6 +4036,311 @@ expand_omp_taskreg (struct omp_region *region)
}
+/* Helper function for expand_omp_{for_*,simd}. If this is the outermost
+ of the combined collapse > 1 loop constructs, generate code like:
+ if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
+ if (cond3 is <)
+ adj = STEP3 - 1;
+ else
+ adj = STEP3 + 1;
+ count3 = (adj + N32 - N31) / STEP3;
+ if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
+ if (cond2 is <)
+ adj = STEP2 - 1;
+ else
+ adj = STEP2 + 1;
+ count2 = (adj + N22 - N21) / STEP2;
+ if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
+ if (cond1 is <)
+ adj = STEP1 - 1;
+ else
+ adj = STEP1 + 1;
+ count1 = (adj + N12 - N11) / STEP1;
+ count = count1 * count2 * count3;
+ Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
+ count = 0;
+ and set ZERO_ITER_BB to that bb. */
+
+/* NOTE: It *could* be better to moosh all of the BBs together,
+ creating one larger BB with all the computation and the unexpected
+ jump at the end. I.e.
+
+ bool zero3, zero2, zero1, zero;
+
+ zero3 = N32 c3 N31;
+ count3 = (N32 - N31) /[cl] STEP3;
+ zero2 = N22 c2 N21;
+ count2 = (N22 - N21) /[cl] STEP2;
+ zero1 = N12 c1 N11;
+ count1 = (N12 - N11) /[cl] STEP1;
+ zero = zero3 || zero2 || zero1;
+ count = count1 * count2 * count3;
+ if (__builtin_expect(zero, false)) goto zero_iter_bb;
+
+ After all, we expect the zero=false, and thus we expect to have to
+ evaluate all of the comparison expressions, so short-circuiting
+ oughtn't be a win. Since the condition isn't protecting a
+ denominator, we're not concerned about divide-by-zero, so we can
+ fully evaluate count even if a numerator turned out to be wrong.
+
+ It seems like putting this all together would create much better
+ scheduling opportunities, and less pressure on the chip's branch
+ predictor. */
+
+static void
+expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
+ basic_block &entry_bb, tree *counts,
+ basic_block &zero_iter_bb, int &first_zero_iter,
+ basic_block &l2_dom_bb)
+{
+ tree t, type = TREE_TYPE (fd->loop.v);
+ gimple stmt;
+ edge e, ne;
+ int i;
+
+ /* Collapsed loops need work for expansion into SSA form. */
+ gcc_assert (!gimple_in_ssa_p (cfun));
+
+ for (i = 0; i < fd->collapse; i++)
+ {
+ tree itype = TREE_TYPE (fd->loops[i].v);
+
+ if (SSA_VAR_P (fd->loop.n2)
+ && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
+ fold_convert (itype, fd->loops[i].n1),
+ fold_convert (itype, fd->loops[i].n2)))
+ == NULL_TREE || !integer_onep (t)))
+ {
+ tree n1, n2;
+ n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
+ n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
+ n2 = force_gimple_operand_gsi (gsi, n2, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
+ NULL_TREE, NULL_TREE);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL))
+ {
+ *gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, gsi);
+ }
+ e = split_block (entry_bb, stmt);
+ if (zero_iter_bb == NULL)
+ {
+ first_zero_iter = i;
+ zero_iter_bb = create_empty_bb (entry_bb);
+ if (current_loops)
+ add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
+ *gsi = gsi_after_labels (zero_iter_bb);
+ stmt = gimple_build_assign (fd->loop.n2,
+ build_zero_cst (type));
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
+ entry_bb);
+ }
+ ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
+ ne->probability = REG_BR_PROB_BASE / 2000 - 1;
+ e->flags = EDGE_TRUE_VALUE;
+ e->probability = REG_BR_PROB_BASE - ne->probability;
+ if (l2_dom_bb == NULL)
+ l2_dom_bb = entry_bb;
+ entry_bb = e->dest;
+ *gsi = gsi_last_bb (entry_bb);
+ }
+
+ if (POINTER_TYPE_P (itype))
+ itype = signed_type_for (itype);
+ t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
+ ? -1 : 1));
+ t = fold_build2 (PLUS_EXPR, itype,
+ fold_convert (itype, fd->loops[i].step), t);
+ t = fold_build2 (PLUS_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].n2));
+ t = fold_build2 (MINUS_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].n1));
+ /* ?? We could probably use CEIL_DIV_EXPR instead of
+ TRUNC_DIV_EXPR and adjusting by hand. Unless we can't
+ generate the same code in the end because generically we
+ don't know that the values involved must be negative for
+ GT?? */
+ if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
+ t = fold_build2 (TRUNC_DIV_EXPR, itype,
+ fold_build1 (NEGATE_EXPR, itype, t),
+ fold_build1 (NEGATE_EXPR, itype,
+ fold_convert (itype,
+ fd->loops[i].step)));
+ else
+ t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].step));
+ t = fold_convert (type, t);
+ if (TREE_CODE (t) == INTEGER_CST)
+ counts[i] = t;
+ else
+ {
+ counts[i] = create_tmp_reg (type, ".count");
+ expand_omp_build_assign (gsi, counts[i], t);
+ }
+ if (SSA_VAR_P (fd->loop.n2))
+ {
+ if (i == 0)
+ t = counts[0];
+ else
+ t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
+ expand_omp_build_assign (gsi, fd->loop.n2, t);
+ }
+ }
+}
+
+
+/* Helper function for expand_omp_{for_*,simd}. Generate code like:
+ T = V;
+ V3 = N31 + (T % count3) * STEP3;
+ T = T / count3;
+ V2 = N21 + (T % count2) * STEP2;
+ T = T / count2;
+ V1 = N11 + T * STEP1;
+ if this loop doesn't have an inner loop construct combined with it. */
+
+static void
+expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
+ tree *counts, tree startvar)
+{
+ int i;
+ tree type = TREE_TYPE (fd->loop.v);
+ tree tem = create_tmp_reg (type, ".tem");
+ gimple stmt = gimple_build_assign (tem, startvar);
+ gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
+
+ for (i = fd->collapse - 1; i >= 0; i--)
+ {
+ tree vtype = TREE_TYPE (fd->loops[i].v), itype, t;
+ itype = vtype;
+ if (POINTER_TYPE_P (vtype))
+ itype = signed_type_for (vtype);
+ if (i != 0)
+ t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
+ else
+ t = tem;
+ t = fold_convert (itype, t);
+ t = fold_build2 (MULT_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].step));
+ if (POINTER_TYPE_P (vtype))
+ t = fold_build_pointer_plus (fd->loops[i].n1, t);
+ else
+ t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
+ t = force_gimple_operand_gsi (gsi, t,
+ DECL_P (fd->loops[i].v)
+ && TREE_ADDRESSABLE (fd->loops[i].v),
+ NULL_TREE, false,
+ GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i].v, t);
+ gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
+ if (i != 0)
+ {
+ t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
+ t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (tem, t);
+ gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
+ }
+ }
+}
+
+
+/* Helper function for expand_omp_for_*. Generate code like:
+ L10:
+ V3 += STEP3;
+ if (V3 cond3 N32) goto BODY_BB; else goto L11;
+ L11:
+ V3 = N31;
+ V2 += STEP2;
+ if (V2 cond2 N22) goto BODY_BB; else goto L12;
+ L12:
+ V2 = N21;
+ V1 += STEP1;
+ goto BODY_BB; */
+
+static basic_block
+extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb,
+ basic_block body_bb)
+{
+ basic_block last_bb, bb, collapse_bb = NULL;
+ int i;
+ gimple_stmt_iterator gsi;
+ edge e;
+ tree t;
+ gimple stmt;
+
+ last_bb = cont_bb;
+ for (i = fd->collapse - 1; i >= 0; i--)
+ {
+ tree vtype = TREE_TYPE (fd->loops[i].v);
+
+ bb = create_empty_bb (last_bb);
+ if (current_loops)
+ add_bb_to_loop (bb, last_bb->loop_father);
+ gsi = gsi_start_bb (bb);
+
+ if (i < fd->collapse - 1)
+ {
+ e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
+ e->probability = REG_BR_PROB_BASE / 8;
+
+ t = fd->loops[i + 1].n1;
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loops[i + 1].v)
+ && TREE_ADDRESSABLE (fd->loops[i
+ + 1].v),
+ NULL_TREE, false,
+ GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i + 1].v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ }
+ else
+ collapse_bb = bb;
+
+ set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
+
+ if (POINTER_TYPE_P (vtype))
+ t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
+ else
+ t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v, fd->loops[i].step);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loops[i].v)
+ && TREE_ADDRESSABLE (fd->loops[i].v),
+ NULL_TREE, false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i].v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+
+ if (i > 0)
+ {
+ t = fd->loops[i].n2;
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ tree v = fd->loops[i].v;
+ if (DECL_P (v) && TREE_ADDRESSABLE (v))
+ v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ 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);
+ e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
+ e->probability = REG_BR_PROB_BASE * 7 / 8;
+ }
+ else
+ make_edge (bb, body_bb, EDGE_FALLTHRU);
+ last_bb = bb;
+ }
+
+ return collapse_bb;
+}
+
+
/* A subroutine of expand_omp_for. Generate code for a parallel
loop with any schedule. Given parameters:
@@ -3816,105 +4503,14 @@ expand_omp_for_generic (struct omp_region *region,
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
if (fd->collapse > 1)
{
- basic_block zero_iter_bb = NULL;
int first_zero_iter = -1;
+ basic_block zero_iter_bb = NULL, l2_dom_bb = NULL;
- /* collapsed loops need work for expansion in SSA form. */
- gcc_assert (!gimple_in_ssa_p (cfun));
- counts = (tree *) alloca (fd->collapse * sizeof (tree));
- for (i = 0; i < fd->collapse; i++)
- {
- tree itype = TREE_TYPE (fd->loops[i].v);
+ counts = XALLOCAVEC (tree, fd->collapse);
+ expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
+ zero_iter_bb, first_zero_iter,
+ l2_dom_bb);
- if (SSA_VAR_P (fd->loop.n2)
- && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
- fold_convert (itype, fd->loops[i].n1),
- fold_convert (itype, fd->loops[i].n2)))
- == NULL_TREE || !integer_onep (t)))
- {
- tree n1, n2;
- n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
- n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
- true, GSI_SAME_STMT);
- n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
- n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
- NULL_TREE, NULL_TREE);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- if (walk_tree (gimple_cond_lhs_ptr (stmt),
- expand_omp_regimplify_p, NULL, NULL)
- || walk_tree (gimple_cond_rhs_ptr (stmt),
- expand_omp_regimplify_p, NULL, NULL))
- {
- gsi = gsi_for_stmt (stmt);
- gimple_regimplify_operands (stmt, &gsi);
- }
- e = split_block (entry_bb, stmt);
- if (zero_iter_bb == NULL)
- {
- first_zero_iter = i;
- zero_iter_bb = create_empty_bb (entry_bb);
- if (current_loops)
- add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
- gsi = gsi_after_labels (zero_iter_bb);
- stmt = gimple_build_assign (fd->loop.n2,
- build_zero_cst (type));
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
- entry_bb);
- }
- ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
- ne->probability = REG_BR_PROB_BASE / 2000 - 1;
- e->flags = EDGE_TRUE_VALUE;
- e->probability = REG_BR_PROB_BASE - ne->probability;
- entry_bb = e->dest;
- gsi = gsi_last_bb (entry_bb);
- }
- if (POINTER_TYPE_P (itype))
- itype = signed_type_for (itype);
- t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
- ? -1 : 1));
- t = fold_build2 (PLUS_EXPR, itype,
- fold_convert (itype, fd->loops[i].step), t);
- t = fold_build2 (PLUS_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].n2));
- t = fold_build2 (MINUS_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].n1));
- if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
- t = fold_build2 (TRUNC_DIV_EXPR, itype,
- fold_build1 (NEGATE_EXPR, itype, t),
- fold_build1 (NEGATE_EXPR, itype,
- fold_convert (itype,
- fd->loops[i].step)));
- else
- t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].step));
- t = fold_convert (type, t);
- if (TREE_CODE (t) == INTEGER_CST)
- counts[i] = t;
- else
- {
- counts[i] = create_tmp_reg (type, ".count");
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_assign (counts[i], t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- }
- if (SSA_VAR_P (fd->loop.n2))
- {
- if (i == 0)
- t = counts[0];
- else
- {
- t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- }
- stmt = gimple_build_assign (fd->loop.n2, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- }
- }
if (zero_iter_bb)
{
/* Some counts[i] vars might be uninitialized if
@@ -3949,18 +4545,21 @@ expand_omp_for_generic (struct omp_region *region,
t4 = build_fold_addr_expr (iend0);
t3 = build_fold_addr_expr (istart0);
t2 = fold_convert (fd->iter_type, fd->loop.step);
- if (POINTER_TYPE_P (type)
- && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
+ t1 = fd->loop.n2;
+ t0 = fd->loop.n1;
+ if (POINTER_TYPE_P (TREE_TYPE (t0))
+ && TYPE_PRECISION (TREE_TYPE (t0))
+ != TYPE_PRECISION (fd->iter_type))
{
/* Avoid casting pointers to integer of a different size. */
tree itype = signed_type_for (type);
- t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
- t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
+ t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
+ t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
}
else
{
- t1 = fold_convert (fd->iter_type, fd->loop.n2);
- t0 = fold_convert (fd->iter_type, fd->loop.n1);
+ t1 = fold_convert (fd->iter_type, t1);
+ t0 = fold_convert (fd->iter_type, t0);
}
if (bias)
{
@@ -4015,64 +4614,38 @@ expand_omp_for_generic (struct omp_region *region,
gsi_remove (&gsi, true);
/* Iteration setup for sequential loop goes in L0_BB. */
+ tree startvar = fd->loop.v;
+ tree endvar = NULL_TREE;
+
gsi = gsi_start_bb (l0_bb);
t = istart0;
if (bias)
t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
- if (POINTER_TYPE_P (type))
- t = fold_convert (signed_type_for (type), t);
- t = fold_convert (type, t);
+ if (POINTER_TYPE_P (TREE_TYPE (startvar)))
+ t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
+ t = fold_convert (TREE_TYPE (startvar), t);
t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loop.v)
- && TREE_ADDRESSABLE (fd->loop.v),
+ DECL_P (startvar)
+ && TREE_ADDRESSABLE (startvar),
NULL_TREE, false, GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loop.v, t);
+ stmt = gimple_build_assign (startvar, t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
t = iend0;
if (bias)
t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
- if (POINTER_TYPE_P (type))
- t = fold_convert (signed_type_for (type), t);
- t = fold_convert (type, t);
+ if (POINTER_TYPE_P (TREE_TYPE (startvar)))
+ t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
+ t = fold_convert (TREE_TYPE (startvar), t);
iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
- if (fd->collapse > 1)
+ if (endvar)
{
- tree tem = create_tmp_reg (type, ".tem");
- stmt = gimple_build_assign (tem, fd->loop.v);
+ stmt = gimple_build_assign (endvar, iend);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- for (i = fd->collapse - 1; i >= 0; i--)
- {
- tree vtype = TREE_TYPE (fd->loops[i].v), itype;
- itype = vtype;
- if (POINTER_TYPE_P (vtype))
- itype = signed_type_for (vtype);
- t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
- t = fold_convert (itype, t);
- t = fold_build2 (MULT_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].step));
- if (POINTER_TYPE_P (vtype))
- t = fold_build_pointer_plus (fd->loops[i].n1, t);
- else
- t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loops[i].v)
- && TREE_ADDRESSABLE (fd->loops[i].v),
- NULL_TREE, false,
- GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loops[i].v, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- if (i != 0)
- {
- t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (tem, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- }
- }
}
+ if (fd->collapse > 1)
+ expand_omp_for_init_vars (fd, &gsi, counts, startvar);
if (!broken_loop)
{
@@ -4084,93 +4657,32 @@ expand_omp_for_generic (struct omp_region *region,
vmain = gimple_omp_continue_control_use (stmt);
vback = gimple_omp_continue_control_def (stmt);
- if (POINTER_TYPE_P (type))
- t = fold_build_pointer_plus (vmain, fd->loop.step);
- else
- t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (vback) && TREE_ADDRESSABLE (vback),
- NULL_TREE, true, GSI_SAME_STMT);
- stmt = gimple_build_assign (vback, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
-
- t = build2 (fd->loop.cond_code, boolean_type_node,
- DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
- iend);
- stmt = gimple_build_cond_empty (t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ /* OMP4 placeholder: if (!gimple_omp_for_combined_p (fd->for_stmt)). */
+ if (1)
+ {
+ if (POINTER_TYPE_P (type))
+ t = fold_build_pointer_plus (vmain, fd->loop.step);
+ else
+ t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (vback)
+ && TREE_ADDRESSABLE (vback),
+ NULL_TREE, true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (vback, t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ t = build2 (fd->loop.cond_code, boolean_type_node,
+ DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
+ iend);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ }
/* Remove GIMPLE_OMP_CONTINUE. */
gsi_remove (&gsi, true);
if (fd->collapse > 1)
- {
- basic_block last_bb, bb;
-
- last_bb = cont_bb;
- for (i = fd->collapse - 1; i >= 0; i--)
- {
- tree vtype = TREE_TYPE (fd->loops[i].v);
-
- bb = create_empty_bb (last_bb);
- if (current_loops)
- add_bb_to_loop (bb, last_bb->loop_father);
- gsi = gsi_start_bb (bb);
-
- if (i < fd->collapse - 1)
- {
- e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
- e->probability = REG_BR_PROB_BASE / 8;
-
- t = fd->loops[i + 1].n1;
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loops[i + 1].v)
- && TREE_ADDRESSABLE
- (fd->loops[i + 1].v),
- NULL_TREE, false,
- GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loops[i + 1].v, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- }
- else
- collapse_bb = bb;
-
- set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
-
- if (POINTER_TYPE_P (vtype))
- t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
- else
- t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
- fd->loops[i].step);
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loops[i].v)
- && TREE_ADDRESSABLE (fd->loops[i].v),
- NULL_TREE, false,
- GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loops[i].v, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
-
- if (i > 0)
- {
- t = fd->loops[i].n2;
- t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
- tree v = fd->loops[i].v;
- if (DECL_P (v) && TREE_ADDRESSABLE (v))
- v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
- 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);
- e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
- e->probability = REG_BR_PROB_BASE * 7 / 8;
- }
- else
- make_edge (bb, l1_bb, EDGE_FALLTHRU);
- last_bb = bb;
- }
- }
+ collapse_bb = extract_omp_for_update_vars (fd, cont_bb, l1_bb);
/* Emit code to get the next parallel iteration in L2_BB. */
gsi = gsi_start_bb (l2_bb);
@@ -4220,19 +4732,27 @@ expand_omp_for_generic (struct omp_region *region,
make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
if (current_loops)
add_bb_to_loop (l2_bb, cont_bb->loop_father);
- if (fd->collapse > 1)
+ e = find_edge (cont_bb, l1_bb);
+ /* OMP4 placeholder for gimple_omp_for_combined_p (fd->for_stmt). */
+ if (0)
+ ;
+ else if (fd->collapse > 1)
{
- e = find_edge (cont_bb, l1_bb);
remove_edge (e);
e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
}
else
+ e->flags = EDGE_TRUE_VALUE;
+ if (e)
{
- e = find_edge (cont_bb, l1_bb);
- e->flags = EDGE_TRUE_VALUE;
+ e->probability = REG_BR_PROB_BASE * 7 / 8;
+ find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
+ }
+ else
+ {
+ e = find_edge (cont_bb, l2_bb);
+ e->flags = EDGE_FALLTHRU;
}
- e->probability = REG_BR_PROB_BASE * 7 / 8;
- find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
set_immediate_dominator (CDI_DOMINATORS, l2_bb,
@@ -4249,10 +4769,14 @@ expand_omp_for_generic (struct omp_region *region,
outer_loop->latch = l2_bb;
add_loop (outer_loop, l0_bb->loop_father);
- struct loop *loop = alloc_loop ();
- loop->header = l1_bb;
- /* The loop may have multiple latches. */
- add_loop (loop, outer_loop);
+ /* OMP4 placeholder: if (!gimple_omp_for_combined_p (fd->for_stmt)). */
+ if (1)
+ {
+ struct loop *loop = alloc_loop ();
+ loop->header = l1_bb;
+ /* The loop may have multiple latches. */
+ add_loop (loop, outer_loop);
+ }
}
}
@@ -4883,6 +5407,295 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
add_loop (loop, trip_loop);
}
+/* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
+ loop. Given parameters:
+
+ for (V = N1; V cond N2; V += STEP) BODY;
+
+ where COND is "<" or ">", we generate pseudocode
+
+ V = N1;
+ goto L1;
+ L0:
+ BODY;
+ V += STEP;
+ L1:
+ if (V cond N2) goto L0; else goto L2;
+ L2:
+
+ For collapsed loops, given parameters:
+ collapse(3)
+ for (V1 = N11; V1 cond1 N12; V1 += STEP1)
+ for (V2 = N21; V2 cond2 N22; V2 += STEP2)
+ for (V3 = N31; V3 cond3 N32; V3 += STEP3)
+ BODY;
+
+ we generate pseudocode
+
+ if (cond3 is <)
+ adj = STEP3 - 1;
+ else
+ adj = STEP3 + 1;
+ count3 = (adj + N32 - N31) / STEP3;
+ if (cond2 is <)
+ adj = STEP2 - 1;
+ else
+ adj = STEP2 + 1;
+ count2 = (adj + N22 - N21) / STEP2;
+ if (cond1 is <)
+ adj = STEP1 - 1;
+ else
+ adj = STEP1 + 1;
+ count1 = (adj + N12 - N11) / STEP1;
+ count = count1 * count2 * count3;
+ V = 0;
+ V1 = N11;
+ V2 = N21;
+ V3 = N31;
+ goto L1;
+ L0:
+ BODY;
+ V += 1;
+ V3 += STEP3;
+ V2 += (V3 cond3 N32) ? 0 : STEP2;
+ V3 = (V3 cond3 N32) ? V3 : N31;
+ V1 += (V2 cond2 N22) ? 0 : STEP1;
+ V2 = (V2 cond2 N22) ? V2 : N21;
+ L1:
+ if (V < count) goto L0; else goto L2;
+ L2:
+
+ */
+
+static void
+expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
+{
+ tree type, t;
+ basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
+ bool broken_loop = region->cont == NULL;
+ edge e, ne;
+ tree *counts = NULL;
+ int i;
+ tree safelen = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
+ OMP_CLAUSE_SAFELEN);
+ tree simduid = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
+ OMP_CLAUSE__SIMDUID_);
+ tree n2;
+
+ type = TREE_TYPE (fd->loop.v);
+ entry_bb = region->entry;
+ cont_bb = region->cont;
+ gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
+ gcc_assert (broken_loop
+ || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
+ l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
+ if (!broken_loop)
+ {
+ gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
+ gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
+ l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
+ l2_bb = BRANCH_EDGE (entry_bb)->dest;
+ }
+ else
+ {
+ BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
+ l1_bb = split_edge (BRANCH_EDGE (entry_bb));
+ l2_bb = single_succ (l1_bb);
+ }
+ exit_bb = region->exit;
+ l2_dom_bb = NULL;
+
+ gsi = gsi_last_bb (entry_bb);
+
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
+ /* Not needed in SSA form right now. */
+ gcc_assert (!gimple_in_ssa_p (cfun));
+ if (fd->collapse > 1)
+ {
+ int first_zero_iter = -1;
+ basic_block zero_iter_bb = l2_bb;
+
+ counts = XALLOCAVEC (tree, fd->collapse);
+ expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
+ zero_iter_bb, first_zero_iter,
+ l2_dom_bb);
+ }
+ if (l2_dom_bb == NULL)
+ l2_dom_bb = l1_bb;
+
+ n2 = fd->loop.n2;
+ if (0)
+ /* Place holder for gimple_omp_for_combined_into_p() in
+ the upcoming gomp-4_0-branch merge. */;
+ else
+ {
+ expand_omp_build_assign (&gsi, fd->loop.v,
+ fold_convert (type, fd->loop.n1));
+ if (fd->collapse > 1)
+ for (i = 0; i < fd->collapse; i++)
+ {
+ tree itype = TREE_TYPE (fd->loops[i].v);
+ if (POINTER_TYPE_P (itype))
+ itype = signed_type_for (itype);
+ t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
+ }
+ }
+
+ /* Remove the GIMPLE_OMP_FOR statement. */
+ gsi_remove (&gsi, true);
+
+ if (!broken_loop)
+ {
+ /* Code to control the increment goes in the CONT_BB. */
+ gsi = gsi_last_bb (cont_bb);
+ stmt = gsi_stmt (gsi);
+ gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+
+ if (POINTER_TYPE_P (type))
+ t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
+ else
+ t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
+ expand_omp_build_assign (&gsi, fd->loop.v, t);
+
+ if (fd->collapse > 1)
+ {
+ i = fd->collapse - 1;
+ if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
+ {
+ t = fold_convert (sizetype, fd->loops[i].step);
+ t = fold_build_pointer_plus (fd->loops[i].v, t);
+ }
+ else
+ {
+ t = fold_convert (TREE_TYPE (fd->loops[i].v),
+ fd->loops[i].step);
+ t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
+ fd->loops[i].v, t);
+ }
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
+
+ for (i = fd->collapse - 1; i > 0; i--)
+ {
+ tree itype = TREE_TYPE (fd->loops[i].v);
+ tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
+ if (POINTER_TYPE_P (itype2))
+ itype2 = signed_type_for (itype2);
+ t = build3 (COND_EXPR, itype2,
+ build2 (fd->loops[i].cond_code, boolean_type_node,
+ fd->loops[i].v,
+ fold_convert (itype, fd->loops[i].n2)),
+ build_int_cst (itype2, 0),
+ fold_convert (itype2, fd->loops[i - 1].step));
+ if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
+ t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
+ else
+ t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
+ expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
+
+ t = build3 (COND_EXPR, itype,
+ build2 (fd->loops[i].cond_code, boolean_type_node,
+ fd->loops[i].v,
+ fold_convert (itype, fd->loops[i].n2)),
+ fd->loops[i].v,
+ fold_convert (itype, fd->loops[i].n1));
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
+ }
+ }
+
+ /* Remove GIMPLE_OMP_CONTINUE. */
+ gsi_remove (&gsi, true);
+ }
+
+ /* Emit the condition in L1_BB. */
+ gsi = gsi_start_bb (l1_bb);
+
+ t = fold_convert (type, n2);
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ t = build2 (fd->loop.cond_code, boolean_type_node, fd->loop.v, t);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt), expand_omp_regimplify_p,
+ NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt), expand_omp_regimplify_p,
+ NULL, NULL))
+ {
+ gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
+
+ /* Remove GIMPLE_OMP_RETURN. */
+ gsi = gsi_last_bb (exit_bb);
+ gsi_remove (&gsi, true);
+
+ /* Connect the new blocks. */
+ remove_edge (FALLTHRU_EDGE (entry_bb));
+
+ if (!broken_loop)
+ {
+ remove_edge (BRANCH_EDGE (entry_bb));
+ make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
+
+ e = BRANCH_EDGE (l1_bb);
+ ne = FALLTHRU_EDGE (l1_bb);
+ e->flags = EDGE_TRUE_VALUE;
+ }
+ else
+ {
+ single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+
+ ne = single_succ_edge (l1_bb);
+ e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
+
+ }
+ ne->flags = EDGE_FALSE_VALUE;
+ e->probability = REG_BR_PROB_BASE * 7 / 8;
+ ne->probability = REG_BR_PROB_BASE / 8;
+
+ set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
+ set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
+ set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
+
+ if (!broken_loop)
+ {
+ struct loop *loop = alloc_loop ();
+ loop->header = l1_bb;
+ loop->latch = e->dest;
+ add_loop (loop, l1_bb->loop_father);
+ if (safelen == NULL_TREE)
+ loop->safelen = INT_MAX;
+ else
+ {
+ safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen);
+ if (!host_integerp (safelen, 1)
+ || (unsigned HOST_WIDE_INT) tree_low_cst (safelen, 1)
+ > INT_MAX)
+ loop->safelen = INT_MAX;
+ else
+ loop->safelen = tree_low_cst (safelen, 1);
+ if (loop->safelen == 1)
+ loop->safelen = 0;
+ }
+ if (simduid)
+ {
+ loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
+ cfun->has_simduid_loops = true;
+ }
+ /* If not -fno-tree-vectorize, hint that we want to vectorize
+ the loop. */
+ if ((flag_tree_vectorize
+ || !global_options_set.x_flag_tree_vectorize)
+ && loop->safelen > 1)
+ {
+ loop->force_vect = true;
+ cfun->has_force_vect_loops = true;
+ }
+ }
+}
+
/* Expand the OpenMP loop defined by REGION. */
@@ -4914,7 +5727,9 @@ expand_omp_for (struct omp_region *region)
original loops from being detected. Fix that up. */
loops_state_set (LOOPS_NEED_FIXUP);
- if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
+ if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_SIMD)
+ expand_omp_simd (region, &fd);
+ else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
&& !fd.have_ordered
&& fd.collapse == 1
&& region->cont != NULL)
@@ -4928,6 +5743,8 @@ expand_omp_for (struct omp_region *region)
{
int fn_index, start_ix, next_ix;
+ gcc_assert (gimple_omp_for_kind (fd.for_stmt)
+ == GF_OMP_FOR_KIND_FOR);
if (fd.chunk_size == NULL
&& fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
fd.chunk_size = integer_zero_node;
@@ -6534,6 +7351,8 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
&& host_integerp (fd->loop.n2, 0)
&& ! integer_zerop (fd->loop.n2))
vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
+ else
+ vinit = unshare_expr (vinit);
/* Initialize the iterator variable, so that threads that don't execute
any iterations don't execute the lastprivate clauses by accident. */
@@ -6557,7 +7376,6 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
push_gimplify_context (&gctx);
lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
- lower_omp (gimple_omp_body_ptr (stmt), ctx);
block = make_node (BLOCK);
new_stmt = gimple_build_bind (NULL, NULL, block);
@@ -6582,6 +7400,8 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
+
/* Lower the header expressions. At this point, we can assume that
the header is of the form:
diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
index 41d2c7605d2..04c6237d791 100644
--- a/gcc/pass_manager.h
+++ b/gcc/pass_manager.h
@@ -74,6 +74,7 @@ public:
return pass_mode_switching_1;
}
opt_pass *get_pass_peephole2 () const { return pass_peephole2_1; }
+ opt_pass *get_pass_profile () const { return pass_profile_1; }
public:
/* The root of the compilation pass tree, once constructed. */
diff --git a/gcc/passes.c b/gcc/passes.c
index e3a7212ccce..5b4975267eb 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -676,6 +676,11 @@ pass_manager::register_one_dump_file (struct opt_pass *pass)
flag_name = concat (prefix, name, num, NULL);
glob_name = concat (prefix, name, NULL);
optgroup_flags |= pass->optinfo_flags;
+ /* For any passes that do not have an optgroup set, and which are not
+ IPA passes setup above, set the optgroup to OPTGROUP_OTHER so that
+ any dump messages are emitted properly under -fopt-info(-optall). */
+ if (optgroup_flags == OPTGROUP_NONE)
+ optgroup_flags = OPTGROUP_OTHER;
id = dump_register (dot_name, flag_name, glob_name, flags, optgroup_flags);
set_pass_for_id (id, pass);
full_name = concat (prefix, pass->name, num, NULL);
@@ -1365,7 +1370,19 @@ void
register_pass (struct register_pass_info *pass_info)
{
g->get_passes ()->register_pass (pass_info);
+}
+
+void
+register_pass (opt_pass* pass, pass_positioning_ops pos,
+ const char* ref_pass_name, int ref_pass_inst_number)
+{
+ register_pass_info i;
+ i.pass = pass;
+ i.reference_pass_name = ref_pass_name;
+ i.ref_pass_instance_number = ref_pass_inst_number;
+ i.pos_op = pos;
+ g->get_passes ()->register_pass (&i);
}
void
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 029c3a25e6d..1ee27428714 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -409,8 +409,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
if (code == FIELD_DECL && DECL_NONADDRESSABLE_P (node))
fputs (" nonaddressable", file);
- if (code == LABEL_DECL && DECL_ERROR_ISSUED (node))
- fputs (" error-issued", file);
if (code == LABEL_DECL && EH_LANDING_PAD_NR (node))
fprintf (file, " landing-pad:%d", EH_LANDING_PAD_NR (node));
diff --git a/gcc/profile.c b/gcc/profile.c
index c469df56dba..2abde8aec03 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -432,8 +432,8 @@ read_profile_edge_counts (gcov_type *exec_counts)
if (flag_profile_correction)
{
static bool informed = 0;
- if (!informed)
- inform (input_location,
+ if (dump_enabled_p () && !informed)
+ dump_printf_loc (MSG_NOTE, input_location,
"corrupted profile info: edge count exceeds maximal count");
informed = 1;
}
@@ -692,10 +692,11 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
{
/* Inconsistency detected. Make it flow-consistent. */
static int informed = 0;
- if (informed == 0)
+ if (dump_enabled_p () && informed == 0)
{
informed = 1;
- inform (input_location, "correcting inconsistent profile data");
+ dump_printf_loc (MSG_NOTE, input_location,
+ "correcting inconsistent profile data");
}
correct_negative_edge_counts ();
/* Set bb counts to the sum of the outgoing edge counts */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 554a81b1cb7..68861a8e1ab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,114 @@
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58228
+ * gcc.dg/torture/pr58228.c: New testcase.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58223
+ * gcc.dg/torture/pr58223.c: New testcase.
+ * gcc.dg/tree-ssa/ldist-16.c: Flip expected behavior.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58010
+ * gcc.dg/pr58010.c: New testcase.
+
+2013-08-29 Xinliang DavidLi <davidxl@google.com>
+
+ * gcc.dg/unroll_3.c: Message change.
+ * gcc.dg/unroll_4.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-1.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-2.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-3.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-4.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-5.c: Likewise.
+ * gcc.dg/tree-ssa/loop-23.c: Likewise.
+ * gcc.dg/tree-ssa/loop-1.c: Likewise.
+ * gcc.dg/unroll_1.c: Likewise.
+ * gcc.dg/vect/bb-slp-31.c: Likewise.
+ * gcc.dg/vect/bb-slp-14.c: Likewise.
+ * gcc.dg/vect/bb-slp-8.c: Likewise.
+ * gcc.dg/vect/bb-slp-23.c: Likewise.
+ * gcc.dg/vect/bb-slp-15.c: Likewise.
+ * gcc.dg/vect/bb-slp-9.c: Likewise.
+ * gcc.dg/vect/bb-slp-24.c: Likewise.
+ * gcc.dg/vect/bb-slp-16.c: Likewise.
+ * gcc.dg/vect/bb-slp-25.c: Likewise.
+ * gcc.dg/vect/bb-slp-17.c: Likewise.
+ * gcc.dg/vect/bb-slp-26.c: Likewise.
+ * gcc.dg/vect/bb-slp-18.c: Likewise.
+ * gcc.dg/vect/no-tree-reassoc-bb-slp-12.c: Likewise.
+ * gcc.dg/vect/bb-slp-27.c: Likewise.
+ * gcc.dg/vect/bb-slp-19.c: Likewise.
+ * gcc.dg/vect/bb-slp-28.c: Likewise.
+ * gcc.dg/vect/bb-slp-cond-1.c: Likewise.
+ * gcc.dg/vect/bb-slp-29.c: Likewise.
+ * gcc.dg/vect/bb-slp-8a.c: Likewise.
+ * gcc.dg/vect/bb-slp-pattern-2.c: Likewise.
+ * gcc.dg/vect/bb-slp-1.c: Likewise.
+ * gcc.dg/vect/bb-slp-8b.c: Likewise.
+ * gcc.dg/vect/bb-slp-2.c: Likewise.
+ * gcc.dg/vect/bb-slp-3.c: Likewise.
+ * gcc.dg/vect/bb-slp-10.c: Likewise.
+ * gcc.dg/vect/fast-math-bb-slp-call-1.c: Likewise.
+ * gcc.dg/vect/bb-slp-4.c: Likewise.
+ * gcc.dg/vect/bb-slp-11.c: Likewise.
+ * gcc.dg/vect/fast-math-bb-slp-call-2.c: Likewise.
+ * gcc.dg/vect/bb-slp-5.c: Likewise.
+ * gcc.dg/vect/bb-slp-20.c: Likewise.
+ * gcc.dg/vect/bb-slp-6.c: Likewise.
+ * gcc.dg/vect/bb-slp-21.c: Likewise.
+ * gcc.dg/vect/bb-slp-30.c: Likewise.
+ * gcc.dg/vect/bb-slp-13.c: Likewise.
+ * gcc.dg/vect/bb-slp-7.c: Likewise.
+ * gcc.dg/vect/bb-slp-22.c: Likewise.
+ * gcc.dg/unroll_2.c: Likewise.
+ * g++.dg/vect/slp-pr50413.cc: Likewise.
+ * g++.dg/vect/slp-pr56812.cc: Likewise.
+ * g++.dg/vect/slp-pr50819.cc: Likewise.
+
+2013-08-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/tree-ssa/ipa-cp-1.c: Adjust regexp.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58246
+ * gcc.dg/torture/pr58246.c: New testcase.
+
+2013-08-29 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/52243
+ * gfortran.dg/realloc_on_assign_14.f90: Remove warning made
+ obsolete by patch.
+ * gfortran.dg/realloc_on_assign_19.f90: New test.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57287
+ * gcc.dg/pr57287-2.c: New testcase.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57685
+ * gcc.dg/torture/pr57685.c: New testcase.
+
+2013-08-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58255
+ * g++.dg/cpp0x/dc7.C: New.
+
+2013-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/58257
+ * c-c++-common/gomp/pr58257.c: New test.
+
+2013-08-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56933
+ * gcc.dg/vect/pr56933.c: Properly guard runtime with check_vect ().
+
2013-08-27 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/scalar_shift_1.c: New.
@@ -180,7 +291,7 @@
* gcc.dg/pr58145-1.c: New test.
* gcc.dg/pr58145-2.c: New test.
-2013-08-14 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-08-14 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.dg/debug/dwarf2/dwarf2.exp: Replace -gdwarf-2 with -gdwarf.
* gcc.dg/debug/dwarf2/dwarf-die7.c: Likewise.
@@ -525,7 +636,7 @@
* gcc.dg/ipa/pr57539.c: New test.
2013-08-06 Martin Jambor <mjambor@suse.cz>
- Bernd Edlinger <bernd.edlinger@hotmail.de>
+ Bernd Edlinger <bernd.edlinger@hotmail.de>
* gcc.dg/torture/pr58041.c (foo): Accept z by reference.
(a): Fix constructor.
@@ -989,7 +1100,7 @@
* gcc.target/aarch64/vabs_intrinsic_1.c: New file.
-2013-07-20 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-07-20 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.dg/pr57154.c: Add dg-require-effective-target scheduling.
@@ -1293,7 +1404,7 @@
PR c++/14263
* g++.dg/inherit/virtual10.C: New.
-2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
PR c/57821
* gcc.dg/large-size-array-6.c: New test.
@@ -1303,7 +1414,7 @@
PR c++/38634
* g++.dg/template/crash116.C: New.
-2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.dg/tree-ssa/vrp66.c: Make conditional on { target { ! int16 } } .
* gcc.dg/tree-ssa/vrp66-int16-sw.c: New test.
@@ -1510,7 +1621,7 @@
* g++.dg/cpp0x/sfinae47.C: New.
-2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
PR target/52483
* gcc.target/sh/pr52483-1.c: New.
@@ -1702,7 +1813,7 @@
* c-c++-common/cilk-plus/AN/if_test.c (main2): Fixed a bug of
accidentally placing minus sign for length instead of stride.
-2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
@@ -1746,7 +1857,7 @@
PR c++/51413
* g++.dg/ext/builtin-offsetof1.C: New.
-2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
+2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/vect_smlal_1.c: New file.
@@ -1785,8 +1896,8 @@
* gcc.dg/tree-ssa/forwprop-27.c: New testcase.
2013-06-12 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/atomic-p7.c: New file, add tests for atomic
load/store instructions on power7, power8.
@@ -1861,8 +1972,8 @@
in how we check __sec_reduce_mutating function's result.
2013-06-10 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/direct-move-vint1.c: New tests for power8
direct move instructions.
@@ -2043,8 +2154,8 @@
* g++.dg/cpp0x/alias-decl-36.C: New.
2013-06-06 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/p8vector-builtin-1.c: New test to test
power8 builtin functions.
@@ -2645,7 +2756,7 @@
PR debug/57351
* gcc.dg/debug/pr57351.c: New test
-2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
+2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/vect-clz.c: New file.
@@ -2683,8 +2794,8 @@
* g++.dg/parse/crash62.C: New.
2013-05-22 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/crypto-builtin-1.c: New file, test for power8
crypto builtins.
@@ -2974,7 +3085,7 @@
(alloca): Remove declaration.
(foo9): Replace alloca by __builtin_alloca.
-2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.c-torture/compile/limits-externdecl.c [target avr-*-*]:
Expect "size of array is too large" error.
@@ -3271,7 +3382,7 @@
* gcc.target/i386/sse2-init-v2di-2.c: Update scan assembler string.
-2013-05-03 Vidya Praveen <vidyapraveen@arm.com>
+2013-05-03 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/fabd.c: New file.
@@ -3968,12 +4079,12 @@
* gcc.dg/vect/slp-39.c: New testcase.
-2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
PR tree-optimization/55524
* gcc.target/epiphany/fnma-1.c: New test.
-2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
+2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
* gcc.dg/tree-ssa/inline-11.c: New test
@@ -4656,7 +4767,7 @@
* gcc.dg/pr56355-1.c: New file.
2013-03-20 Catherine Moore <clm@codesourcery.com>
- Richard Sandiford <rdsandiford@googlemail.com>
+ Richard Sandiford <rdsandiford@googlemail.com>
* gcc.target/mips/mips.exp: Add microMIPS support.
* gcc.target/mips/umips-movep-2.c: New test.
diff --git a/gcc/testsuite/c-c++-common/gomp/pr58257.c b/gcc/testsuite/c-c++-common/gomp/pr58257.c
new file mode 100644
index 00000000000..8f8d24a998a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr58257.c
@@ -0,0 +1,15 @@
+/* PR middle-end/58257 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp -Wall" } */
+
+int
+foo (int n)
+{
+ int a[10][10];
+ int x, y;
+#pragma omp parallel for collapse(2) /* { dg-bogus "may be used uninitialized in this function" } */
+ for (x = 0; x < n; x++) /* { dg-bogus "may be used uninitialized in this function" } */
+ for (y = 0; y < n; y++)
+ a[x][y] = x + y * y;
+ return a[0][0];
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/dc7.C b/gcc/testsuite/g++.dg/cpp0x/dc7.C
new file mode 100644
index 00000000000..e48741e0713
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/dc7.C
@@ -0,0 +1,7 @@
+// PR c++/58255
+// { dg-do compile { target c++11 } }
+
+struct A {
+ explicit A() { }
+ A(int x) : A() { }
+};
diff --git a/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
index 5513d3650c6..91f43ae8c0b 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
@@ -1,7 +1,7 @@
// PR tree-optimization/39557
// invalid post-dom info leads to infinite loop
// { dg-do run }
-// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fno-rtti" }
+// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fopt-info -fno-rtti" }
struct C
{
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr50413.cc b/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
index c47caf10747..6e69f11b382 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
@@ -160,6 +160,6 @@ void shift(unsigned char t)
V.bitmap.b96 = t;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr50819.cc b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
index 96f82c30218..515d774a228 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
@@ -49,5 +49,5 @@ const & v2) {
res = res + s*(v1+v2);
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr56812.cc b/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
index 9570fb31e86..e98abc89df0 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
@@ -17,5 +17,5 @@ void mydata::Set (float x)
data[i] = x;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/inline-dump.c b/gcc/testsuite/gcc.dg/inline-dump.c
new file mode 100644
index 00000000000..e0c9ba6993c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-dump.c
@@ -0,0 +1,11 @@
+/* Verify that -fopt-info can output correct inline info. */
+/* { dg-do compile } */
+/* { dg-options "-Wall -fopt-info-inline=stderr -O2 -fno-early-inlining" } */
+static inline int leaf() {
+ int i, ret = 0;
+ for (i = 0; i < 10; i++)
+ ret += i;
+ return ret;
+}
+static inline int foo(void) { return leaf(); } /* { dg-message "note: leaf .*inlined into bar .*via inline instance foo.*\n" } */
+int bar(void) { return foo(); }
diff --git a/gcc/testsuite/gcc.dg/pr26570.c b/gcc/testsuite/gcc.dg/pr26570.c
index 5768d32cc12..71c16f20744 100644
--- a/gcc/testsuite/gcc.dg/pr26570.c
+++ b/gcc/testsuite/gcc.dg/pr26570.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fprofile-generate -fprofile-use" } */
+/* { dg-options "-O2 -fprofile-generate -fprofile-use -fopt-info" } */
unsigned test (unsigned a, unsigned b)
{
diff --git a/gcc/testsuite/gcc.dg/pr32773.c b/gcc/testsuite/gcc.dg/pr32773.c
index e9cdd4c377e..19a90195ad3 100644
--- a/gcc/testsuite/gcc.dg/pr32773.c
+++ b/gcc/testsuite/gcc.dg/pr32773.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O -fprofile-use" } */
-/* { dg-options "-O -m4 -fprofile-use" { target sh-*-* } } */
+/* { dg-options "-O -fprofile-use -fopt-info" } */
+/* { dg-options "-O -m4 -fprofile-use -fopt-info" { target sh-*-* } } */
void foo (int *p)
{
diff --git a/gcc/testsuite/gcc.dg/pr40209.c b/gcc/testsuite/gcc.dg/pr40209.c
index f367f7c2472..afe131fc5eb 100644
--- a/gcc/testsuite/gcc.dg/pr40209.c
+++ b/gcc/testsuite/gcc.dg/pr40209.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fprofile-use" } */
+/* { dg-options "-O2 -fprofile-use -fopt-info" } */
void process(const char *s);
diff --git a/gcc/testsuite/gcc.dg/pr57287-2.c b/gcc/testsuite/gcc.dg/pr57287-2.c
new file mode 100644
index 00000000000..5422e148cbe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr57287-2.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+#include <setjmp.h>
+
+struct node
+{
+ struct node *next;
+ char *name;
+} *list;
+
+struct node *list;
+struct node *head (void);
+
+sigjmp_buf *bar (void);
+
+int baz (void)
+{
+ struct node *n;
+ int varseen = 0;
+
+ list = head ();
+ for (n = list; n; n = n->next)
+ {
+ if (!varseen)
+ varseen = 1;
+
+ sigjmp_buf *buf = bar (); /* { dg-bogus "may be used uninitialized" "" } */
+ __sigsetjmp (*buf, 1);
+ }
+
+ if (!varseen)
+ return 0;
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/pr58010.c b/gcc/testsuite/gcc.dg/pr58010.c
new file mode 100644
index 00000000000..a0fbd31f495
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr58010.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -funswitch-loops -ftree-vectorize" } */
+
+short a, b, c, d;
+
+void f(void)
+{
+ short e;
+
+ for(; e; e++)
+ for(; b; b++);
+
+ for(d = 0; d < 4; d++)
+ a ^= (e ^= 1) || c ? : e;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57685.c b/gcc/testsuite/gcc.dg/torture/pr57685.c
new file mode 100644
index 00000000000..75973f2a493
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57685.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+unsigned f(void)
+{
+ unsigned a;
+ int b, c, d, e;
+
+ for(c = 27; c < 40; c++)
+ b |= d |= b;
+
+ if(b)
+ a = e;
+
+ return a;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58223.c b/gcc/testsuite/gcc.dg/torture/pr58223.c
new file mode 100644
index 00000000000..978084ad0dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58223.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int a[2], b;
+
+int main ()
+{
+ for (b = 0; b < 2; b++)
+ {
+ a[0] = 1;
+ a[b] = 0;
+ }
+ if (a[0] != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58228.c b/gcc/testsuite/gcc.dg/torture/pr58228.c
new file mode 100644
index 00000000000..d12303a008d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58228.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int a[8][8] = {{1}};
+int b, c, d, e;
+
+int main ()
+{
+ for (c = 0; c < 8; c++)
+ for (b = 0; b < 2; b++)
+ a[b + 4][c] = a[c][0];
+ if (a[4][4] != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58246.c b/gcc/testsuite/gcc.dg/torture/pr58246.c
new file mode 100644
index 00000000000..5417abf913d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58246.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int a, b;
+
+int main ()
+{
+ int t[2] = {1,1};
+
+ for (a = 0; a < 2; a++)
+ {
+ b ^= t[a];
+ t[a] = t[1] = 0;
+ }
+
+ if (b != 1)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
index 6220640459d..0bea9a9f00b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
@@ -8,6 +8,6 @@ test(int c)
a[i]=5;
}
/* Array bounds says the loop will not roll much. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 2 times" "cunrolli"} } */
+/* { dg-final { scan-tree-dump "loop with 3 iterations completely unrolled" "cunrolli"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunrolli"} } */
/* { dg-final { cleanup-tree-dump "cunrolli" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
index 10f6645cf25..e16d0086fab 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
@@ -12,5 +12,5 @@ test(int c)
}
}
/* We are not able to get rid of the final conditional because the loop has two exits. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunroll"} } */
+/* { dg-final { scan-tree-dump "loop with 2 iterations completely unrolled" "cunroll"} } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
index 44de9606e9c..dd6ce506744 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
@@ -11,5 +11,5 @@ test(int c)
}
/* If we start duplicating headers prior curoll, this loop will have 0 iterations. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunrolli"} } */
+/* { dg-final { scan-tree-dump "loop with 2 iterations completely unrolled" "cunrolli"} } */
/* { dg-final { cleanup-tree-dump "cunrolli" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
index 9b70e95949f..86e12bbb419 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
@@ -16,6 +16,6 @@ test(int c)
/* We should do this as part of cunrolli, but our cost model do not take into account early exit
from the last iteration. */
-/* { dg-final { scan-tree-dump "Turned loop into non-loop; it never loops." "ivcanon"} } */
+/* { dg-final { scan-tree-dump "loop turned into non-loop; it never loops." "ivcanon"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "ivcanon"} } */
/* { dg-final { cleanup-tree-dump "ivcanon" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
index f74e6b5093b..1e9b8bfbab0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
@@ -8,7 +8,7 @@ test(int c)
a[i]=5;
}
/* Basic testcase for complette unrolling. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 5 times" "cunroll"} } */
+/* { dg-final { scan-tree-dump "loop with 6 iterations completely unrolled" "cunroll"} } */
/* { dg-final { scan-tree-dump "Exit condition of peeled iterations was eliminated." "cunroll"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
index 5d087aa45dd..ec628b777a9 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
@@ -16,5 +16,5 @@ blah ()
very_long_function (1);
}
/* One appearance for dump, one self recursive call and one call from main. */
-/* { dg-final { scan-tree-dump-times "very_long_function.constprop.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "very_long_function.constprop \\(\\)" 3 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c
index a26999e8905..53a9fa4f9e3 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c
@@ -14,8 +14,8 @@ void foo (int n)
}
}
-/* We should apply loop distribution and generate a memset (0). */
+/* We should not apply loop distribution and not generate a memset (0). */
-/* { dg-final { scan-tree-dump "distributed: split to 2" "ldist" } } */
-/* { dg-final { scan-tree-dump-times "generated memset zero" 1 "ldist" } } */
+/* { dg-final { scan-tree-dump "Loop 1 is the same" "ldist" } } */
+/* { dg-final { scan-tree-dump-times "generated memset zero" 0 "ldist" } } */
/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
index b4e4f2ac798..dd52c50faf4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
@@ -35,7 +35,7 @@ int xxx(void)
/* { dg-final { scan-tree-dump-times "Added canonical iv to loop 1, 4 iterations" 1 "ivcanon"} } */
/* { dg-final { cleanup-tree-dump "ivcanon" } } */
-/* { dg-final { scan-tree-dump-times "Completely unroll loop 4 times" 1 "cunroll"} } */
+/* { dg-final { scan-tree-dump-times "loop with 5 iterations completely unrolled" 1 "cunroll"} } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
/* { dg-final { scan-tree-dump-times "foo" 5 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
index 4f42491dad2..5bdc35fbd4c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
@@ -24,6 +24,6 @@ int foo(void)
return sum;
}
-/* { dg-final { scan-tree-dump-times "Completely unroll loop 3 times" 1 "cunroll" } } */
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 1 "cunroll" } } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/unroll_1.c b/gcc/testsuite/gcc.dg/unroll_1.c
index 5818635cea9..a02825f2b0d 100644
--- a/gcc/testsuite/gcc.dg/unroll_1.c
+++ b/gcc/testsuite/gcc.dg/unroll_1.c
@@ -28,5 +28,5 @@ int foo2(void)
return 1;
}
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 2 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "loop turned into non-loop; it never loops" 2 "loop2_unroll" } } */
/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/unroll_2.c b/gcc/testsuite/gcc.dg/unroll_2.c
index 1156b2cc88d..601b38705c1 100644
--- a/gcc/testsuite/gcc.dg/unroll_2.c
+++ b/gcc/testsuite/gcc.dg/unroll_2.c
@@ -28,5 +28,5 @@ int foo2(void)
return 1;
}
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "loop turned into non-loop; it never loops" 1 "loop2_unroll" } } */
/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/unroll_3.c b/gcc/testsuite/gcc.dg/unroll_3.c
index 13e815f18be..1f4216b6068 100644
--- a/gcc/testsuite/gcc.dg/unroll_3.c
+++ b/gcc/testsuite/gcc.dg/unroll_3.c
@@ -28,5 +28,5 @@ int foo2(void)
return 1;
}
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "loop turned into non-loop; it never loops" 1 "loop2_unroll" } } */
/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/unroll_4.c b/gcc/testsuite/gcc.dg/unroll_4.c
index 59f75edf3db..33d6edee2cc 100644
--- a/gcc/testsuite/gcc.dg/unroll_4.c
+++ b/gcc/testsuite/gcc.dg/unroll_4.c
@@ -28,5 +28,5 @@ int foo2(void)
return 1;
}
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "loop turned into non-loop; it never loops" 1 "loop2_unroll" } } */
/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
index 11882ec5d4a..1caa3cf5c60 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
@@ -56,6 +56,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
index 6eb8f5465f8..658bf03ca56 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
@@ -50,6 +50,6 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" { xfail vect_element_align } } } */
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
index 9844788ea0d..3c350a7ab22 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
@@ -48,6 +48,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect64 } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect64 } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
index f312ea64fc1..88838cea9bc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
index 9a36033ca7b..d46deadd0dc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
index 842699ecb0a..fd065e6ce35 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
@@ -51,6 +51,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
index 609dc7b6a3e..0cbec65b773 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
@@ -65,6 +65,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
index 5a917b8b3f7..3f14ff487a5 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
@@ -57,6 +57,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
index 98501ccf6a6..7d73dbd8b23 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
index 2f726121c94..576bbc16921 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
@@ -53,6 +53,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
index da228f7c33c..accc472f791 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
@@ -53,6 +53,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
index caaecb9bafb..a7978a70d7a 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
index eba9d08c951..8ad71454afe 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
index 30bc57a6bbb..e425dc9ade1 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { ! {vect_int_mult } } } } } */
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { ! {vect_int_mult } } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
index a736c385c81..35f5186fd74 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
@@ -51,6 +51,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
index 10d8e406647..d0c1d69d1fa 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
index b92535df00c..737b3b06c04 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
index f40c12402b6..881f3204f40 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
@@ -55,6 +55,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect64 } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect64 } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
index e9b386f4921..7fcc1e61041 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
@@ -44,6 +44,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
index 3dc1a0d8a7c..650c50eb938 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
@@ -66,6 +66,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
index c2bc391885d..c5b31343a44 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && vect_element_align } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_int_mult && vect_element_align } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
index 98cbc5b80ea..093389faf9f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
@@ -42,6 +42,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
index a587780364f..86da55a47cc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
@@ -43,5 +43,5 @@ test1(void)
int main() { test1(); return a[21]; }
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
index e2704dc721f..bbddb0ac28c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
@@ -9,4 +9,4 @@ void f(){
a[1]=1+2*a[1]*a[1];
}
-/* { dg-final { scan-tree-dump "Vectorized basic-block" "slp" } } */
+/* { dg-final { scan-tree-dump "basic block vectorized" "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
index 5b983c7e63e..2c4b62dc4ac 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
@@ -38,6 +38,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
index cd1679e981d..ca093e795fc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
index 39d8c04cc9a..c233a9d5010 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
@@ -45,6 +45,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
index c0ca017d0d8..b7b90f0b95b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
index 1cb3ddd65e6..303fe3e4336 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
@@ -48,6 +48,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
index 9db6747985e..55a6a81d38c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
index dc6353999f3..8c5c5ab9182 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
@@ -49,6 +49,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
index 3b950897249..9f1a5877a29 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
index 38c18a71fc7..86376b44641 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
@@ -41,6 +41,6 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
index 0d4d54fe0c2..545c08d86e9 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
@@ -48,5 +48,5 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_element_align && vect_pack_trunc } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_element_align && vect_pack_trunc } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
index d842658c679..c138a78b328 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
@@ -45,5 +45,5 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
index d6fb6a2b6f9..c126c1c0085 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
@@ -63,5 +63,5 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" { target vect_call_lrint } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp" { target vect_call_lrint } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
index b4154835a11..49274f88f57 100644
--- a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
+++ b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr56933.c b/gcc/testsuite/gcc.dg/vect/pr56933.c
index 93a7da2ee8d..b5e56fbddc9 100644
--- a/gcc/testsuite/gcc.dg/vect/pr56933.c
+++ b/gcc/testsuite/gcc.dg/vect/pr56933.c
@@ -1,4 +1,7 @@
/* { dg-do run } */
+/* { dg-require-effective-target vect_double } */
+
+#include "tree-vect.h"
extern void abort (void);
void __attribute__((noinline,noclone))
@@ -17,6 +20,9 @@ int main()
{
double b[1024], d[2*1024], f[1024];
int i;
+
+ check_vect ();
+
for (i = 0; i < 2*1024; i++)
d[i] = 1.;
foo (b, d, f);
diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90
index 8474d18622d..b8b669f640d 100644
--- a/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90
+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90
@@ -23,7 +23,7 @@ str = 'abc' ! { dg-warning "Code for reallocating the allocatable variable" }
astr = 'abc' ! no realloc
astr = ['abc'] ! { dg-warning "Code for reallocating the allocatable array" }
a = reshape(a,shape(a)) ! { dg-warning "Code for reallocating the allocatable array" }
-r = sin(r) ! { dg-warning "Code for reallocating the allocatable array" }
+r = sin(r)
r = sin(r(1)) ! no realloc
b = sin(r(1)) ! { dg-warning "Code for reallocating the allocatable variable" }
diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_19.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_19.f90
new file mode 100644
index 00000000000..c54a35f40da
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_19.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! PR 52243 - avoid check for reallocation when doing simple
+! assignments with the same variable on both sides.
+module foo
+contains
+ elemental function ele(a)
+ real, intent(in) :: a
+ real :: ele
+ ele = 1./(2+a)
+ end function ele
+
+ subroutine bar(a)
+ real, dimension(:), allocatable :: a
+ a = a * 2.0
+ a = sin(a-0.3)
+ a = ele(a)
+ end subroutine bar
+end module foo
+! { dg-final { scan-tree-dump-times "alloc" 0 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 10431c09237..5bd7719516b 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -4331,10 +4331,25 @@ get_references_in_stmt (gimple stmt, vec<data_ref_loc, va_stack> *references)
/* ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
As we cannot model data-references to not spelled out
accesses give up if they may occur. */
- if ((stmt_code == GIMPLE_CALL
- && !(gimple_call_flags (stmt) & ECF_CONST))
- || (stmt_code == GIMPLE_ASM
- && (gimple_asm_volatile_p (stmt) || gimple_vuse (stmt))))
+ if (stmt_code == GIMPLE_CALL
+ && !(gimple_call_flags (stmt) & ECF_CONST))
+ {
+ /* Allow IFN_GOMP_SIMD_LANE in their own loops. */
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
+ {
+ struct loop *loop = gimple_bb (stmt)->loop_father;
+ tree uid = gimple_call_arg (stmt, 0);
+ gcc_assert (TREE_CODE (uid) == SSA_NAME);
+ if (loop == NULL
+ || loop->simduid != SSA_NAME_VAR (uid))
+ clobbers_memory = true;
+ }
+ else
+ clobbers_memory = true;
+ }
+ else if (stmt_code == GIMPLE_ASM
+ && (gimple_asm_volatile_p (stmt) || gimple_vuse (stmt)))
clobbers_memory = true;
if (!gimple_vuse (stmt))
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 01e65621092..ab42470f19a 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -344,7 +344,6 @@ extern struct omp_region *new_omp_region (basic_block, enum gimple_code,
struct omp_region *);
extern void free_omp_regions (void);
void omp_expand_local (basic_block);
-extern tree find_omp_clause (tree, enum omp_clause_code);
tree copy_var_decl (tree, tree, tree);
/*---------------------------------------------------------------------------
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 6ec9c0f5050..3ef356a0ac7 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -1787,6 +1787,10 @@ main_tree_if_conversion (void)
return 0;
FOR_EACH_LOOP (li, loop, 0)
+ if (flag_tree_loop_if_convert == 1
+ || flag_tree_loop_if_convert_stores == 1
+ || flag_tree_vectorize
+ || loop->force_vect)
changed |= tree_if_conversion (loop);
if (changed)
@@ -1811,7 +1815,8 @@ main_tree_if_conversion (void)
static bool
gate_tree_if_conversion (void)
{
- return ((flag_tree_vectorize && flag_tree_loop_if_convert != 0)
+ return (((flag_tree_vectorize || cfun->has_force_vect_loops)
+ && flag_tree_loop_if_convert != 0)
|| flag_tree_loop_if_convert == 1
|| flag_tree_loop_if_convert_stores == 1);
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 55e527014f1..af26c85150d 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1298,7 +1298,8 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
case GIMPLE_OMP_FOR:
s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
s2 = remap_gimple_seq (gimple_omp_for_pre_body (stmt), id);
- copy = gimple_build_omp_for (s1, gimple_omp_for_clauses (stmt),
+ copy = gimple_build_omp_for (s1, gimple_omp_for_kind (stmt),
+ gimple_omp_for_clauses (stmt),
gimple_omp_for_collapse (stmt), s2);
{
size_t i;
@@ -2399,6 +2400,8 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
get_loop (src_cfun, 0));
/* Defer to cfgcleanup to update loop-father fields of basic-blocks. */
loops_state_set (LOOPS_NEED_FIXUP);
+ cfun->has_force_vect_loops |= src_cfun->has_force_vect_loops;
+ cfun->has_simduid_loops |= src_cfun->has_simduid_loops;
}
/* If the loop tree in the source function needed fixup, mark the
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 2317edcc7a3..95c4d5f753a 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -542,17 +542,19 @@ already_processed_vertex_p (bitmap processed, int v)
|| !bitmap_bit_p (remaining_stmts, v));
}
-/* Returns NULL when there is no anti-dependence among the successors
- of vertex V, otherwise returns the edge with the anti-dep. */
+/* Returns NULL when there is no anti-dependence or output-dependence
+ among the successors of vertex V, otherwise returns the edge with the
+ dependency. */
static struct graph_edge *
-has_anti_dependence (struct vertex *v)
+has_anti_or_output_dependence (struct vertex *v)
{
struct graph_edge *e;
if (v->succ)
for (e = v->succ; e; e = e->succ_next)
- if (RDGE_TYPE (e) == anti_dd)
+ if (RDGE_TYPE (e) == anti_dd
+ || RDGE_TYPE (e) == output_dd)
return e;
return NULL;
@@ -604,11 +606,10 @@ mark_nodes_having_upstream_mem_writes (struct graph *rdg)
|| predecessor_has_mem_write (rdg, &(rdg->vertices[x]))
/* In anti dependences the read should occur before
the write, this is why both the read and the write
- should be placed in the same partition. */
- || has_anti_dependence (&(rdg->vertices[x])))
- {
- bitmap_set_bit (upstream_mem_writes, x);
- }
+ should be placed in the same partition. In output
+ dependences the writes order need to be preserved. */
+ || has_anti_or_output_dependence (&(rdg->vertices[x])))
+ bitmap_set_bit (upstream_mem_writes, x);
}
nodes.release ();
@@ -637,7 +638,7 @@ rdg_flag_uses (struct graph *rdg, int u, partition_t partition, bitmap loops,
use_operand_p use_p;
struct vertex *x = &(rdg->vertices[u]);
gimple stmt = RDGV_STMT (x);
- struct graph_edge *anti_dep = has_anti_dependence (x);
+ struct graph_edge *anti_dep = has_anti_or_output_dependence (x);
/* Keep in the same partition the destination of an antidependence,
because this is a store to the exact same location. Putting this
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 04167455915..9d413c7fb42 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -1695,7 +1695,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
t = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
- for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
+ for_stmt = gimple_build_omp_for (NULL, GF_OMP_FOR_KIND_FOR, t, 1, NULL);
gimple_set_location (for_stmt, loc);
gimple_omp_for_set_index (for_stmt, 0, initvar);
gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 787a49b7c41..a6d8a8311a6 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -91,7 +91,8 @@ public:
virtual opt_pass *clone ();
/* If has_gate is set, this pass and all sub-passes are executed only if
- the function returns true. */
+ the function returns true.
+ The default implementation returns true. */
virtual bool gate ();
/* This is the code to run. If has_execute is false, then there should
@@ -330,6 +331,14 @@ struct register_pass_info
enum pass_positioning_ops pos_op; /* how to insert the new pass. */
};
+/* Registers a new pass. Either fill out the register_pass_info or specify
+ the individual parameters. The pass object is expected to have been
+ allocated using operator new and the pass manager takes the ownership of
+ the pass object. */
+extern void register_pass (register_pass_info *);
+extern void register_pass (opt_pass* pass, pass_positioning_ops pos,
+ const char* ref_pass_name, int ref_pass_inst_number);
+
extern gimple_opt_pass *make_pass_mudflap_1 (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_mudflap_2 (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_asan (gcc::context *ctxt);
@@ -594,7 +603,6 @@ extern void ipa_read_summaries (void);
extern void ipa_read_optimization_summaries (void);
extern void register_one_dump_file (struct opt_pass *);
extern bool function_called_by_processed_nodes_p (void);
-extern void register_pass (struct register_pass_info *);
/* Set to true if the pass is called the first time during compilation of the
current function. Note that using this information in the optimization
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 541269955d0..69e40060727 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -316,11 +316,14 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
case OMP_CLAUSE_COPYPRIVATE:
name = "copyprivate";
goto print_remap;
+ case OMP_CLAUSE_UNIFORM:
+ name = "uniform";
+ goto print_remap;
print_remap:
pp_string (buffer, name);
pp_left_paren (buffer);
dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
- spc, flags, false);
+ spc, flags, false);
pp_right_paren (buffer);
break;
@@ -433,6 +436,30 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
pp_string (buffer, "mergeable");
break;
+ case OMP_CLAUSE_LINEAR:
+ pp_string (buffer, "linear(");
+ dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+ spc, flags, false);
+ pp_character (buffer, ':');
+ dump_generic_node (buffer, OMP_CLAUSE_LINEAR_STEP (clause),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
+ case OMP_CLAUSE_SAFELEN:
+ pp_string (buffer, "safelen(");
+ dump_generic_node (buffer, OMP_CLAUSE_SAFELEN_EXPR (clause),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
+ case OMP_CLAUSE__SIMDUID_:
+ pp_string (buffer, "_simduid_(");
+ dump_generic_node (buffer, OMP_CLAUSE__SIMDUID__DECL (clause),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
default:
/* Should never happen. */
dump_generic_node (buffer, clause, spc, flags, false);
@@ -2179,6 +2206,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case OMP_FOR:
pp_string (buffer, "#pragma omp for");
+ goto dump_omp_loop;
+
+ case OMP_SIMD:
+ pp_string (buffer, "#pragma omp simd");
+ goto dump_omp_loop;
+
+ dump_omp_loop:
dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
if (!(flags & TDF_SLIM))
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 78687f7fac8..3ba321d6181 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -631,6 +631,22 @@ likely_value (gimple stmt)
if (has_constant_operand)
all_undefined_operands = false;
+ if (has_undefined_operand
+ && code == GIMPLE_CALL
+ && gimple_call_internal_p (stmt))
+ switch (gimple_call_internal_fn (stmt))
+ {
+ /* These 3 builtins use the first argument just as a magic
+ way how to find out a decl uid. */
+ case IFN_GOMP_SIMD_LANE:
+ case IFN_GOMP_SIMD_VF:
+ case IFN_GOMP_SIMD_LAST_LANE:
+ has_undefined_operand = false;
+ break;
+ default:
+ break;
+ }
+
/* If the operation combines operands like COMPLEX_EXPR make sure to
not mark the result UNDEFINED if only one part of the result is
undefined. */
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 75ab54aeda6..9bc455c61a7 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -60,7 +60,13 @@ may_propagate_copy (tree dest, tree orig)
/* If ORIG flows in from an abnormal edge, it cannot be propagated. */
if (TREE_CODE (orig) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)
+ /* If it is the default definition and an automatic variable then
+ we can though and it is important that we do to avoid
+ uninitialized regular copies. */
+ && !(SSA_NAME_IS_DEFAULT_DEF (orig)
+ && (SSA_NAME_VAR (orig) == NULL_TREE
+ || TREE_CODE (SSA_NAME_VAR (orig)) == VAR_DECL)))
return false;
/* If DEST is an SSA_NAME that flows from an abnormal edge, then it
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 4fd3cd8ad24..22ae50b791c 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -574,6 +574,11 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data)
in the references (gcc.c-torture/execute/pr42142.c).
The simplest way is to check if the kill dominates
the use. */
+ /* But when both are in the same block we cannot
+ easily tell whether we came from a backedge
+ unless we decide to compute stmt UIDs
+ (see PR58246). */
+ && (basic_block) data != gimple_bb (def_stmt)
&& dominated_by_p (CDI_DOMINATORS, (basic_block) data,
gimple_bb (def_stmt))
&& operand_equal_p (ref->ref, lhs, 0))
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 735403a0284..f2acc4c15f1 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -870,11 +870,12 @@ try_unroll_loop_completely (struct loop *loop,
{
if (!n_unroll)
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
- "Turned loop into non-loop; it never loops.\n");
+ "loop turned into non-loop; it never loops\n");
else
{
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
- "Completely unroll loop %d times", (int)n_unroll);
+ "loop with %d iterations completely unrolled",
+ (int) (n_unroll + 1));
if (profile_info)
dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS,
" (header execution count %d)",
@@ -1125,6 +1126,11 @@ tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer,
if (changed)
return true;
+ /* Don't unroll #pragma omp simd loops until the vectorizer
+ attempts to vectorize those. */
+ if (loop->force_vect)
+ return false;
+
/* Try to unroll this loop. */
loop_father = loop_outer (loop);
if (!loop_father)
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 717f54ee932..8bcfd060e60 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -314,7 +314,7 @@ tree_vectorize (void)
static bool
gate_tree_vectorize (void)
{
- return flag_tree_vectorize;
+ return flag_tree_vectorize || cfun->has_force_vect_loops;
}
namespace {
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 320dec52afd..fc33647cfc8 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -761,14 +761,6 @@ thread_around_empty_block (edge taken_edge,
gimple stmt;
tree cond;
- /* This block must have a single predecessor (E->dest). */
- if (!single_pred_p (bb))
- return NULL;
-
- /* This block must have more than one successor. */
- if (single_succ_p (bb))
- return NULL;
-
/* This block can have no PHI nodes. This is overly conservative. */
if (!gsi_end_p (gsi_start_phis (bb)))
return NULL;
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 259a691e326..8a872a3f9f7 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -1146,17 +1146,56 @@ mark_threaded_blocks (bitmap threaded_blocks)
edge e;
edge_iterator ei;
+ /* It is possible to have jump threads in which one is a subpath
+ of the other. ie, (A, B), (B, C), (C, D) where B is a joiner
+ block and (B, C), (C, D) where no joiner block exists.
+
+ When this occurs ignore the jump thread request with the joiner
+ block. It's totally subsumed by the simpler jump thread request.
+
+ This results in less block copying, simpler CFGs. More improtantly,
+ when we duplicate the joiner block, B, in this case we will create
+ a new threading opportunity that we wouldn't be able to optimize
+ until the next jump threading iteration.
+
+ So first convert the jump thread requests which do not require a
+ joiner block. */
for (i = 0; i < threaded_edges.length (); i += 3)
{
edge e = threaded_edges[i];
- edge *x = XNEWVEC (edge, 2);
- e->aux = x;
- THREAD_TARGET (e) = threaded_edges[i + 1];
- THREAD_TARGET2 (e) = threaded_edges[i + 2];
- bitmap_set_bit (tmp, e->dest->index);
+ if (threaded_edges[i + 2] == NULL)
+ {
+ edge *x = XNEWVEC (edge, 2);
+
+ e->aux = x;
+ THREAD_TARGET (e) = threaded_edges[i + 1];
+ THREAD_TARGET2 (e) = NULL;
+ bitmap_set_bit (tmp, e->dest->index);
+ }
}
+
+ /* Now iterate again, converting cases where we threaded through
+ a joiner block, but ignoring those where we have already
+ threaded through the joiner block. */
+ for (i = 0; i < threaded_edges.length (); i += 3)
+ {
+ edge e = threaded_edges[i];
+
+ if (threaded_edges[i + 2] != NULL
+ && threaded_edges[i + 1]->aux == NULL)
+ {
+ edge *x = XNEWVEC (edge, 2);
+
+ e->aux = x;
+ THREAD_TARGET (e) = threaded_edges[i + 1];
+ THREAD_TARGET2 (e) = threaded_edges[i + 2];
+ bitmap_set_bit (tmp, e->dest->index);
+ }
+ }
+
+
/* If optimizing for size, only thread through block if we don't have
to duplicate it or it's an otherwise empty redirection block. */
if (optimize_function_for_size_p (cfun))
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index 9efd0991041..a86bcd87c1a 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -209,7 +209,6 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
if (TREE_CODE (expr) == LABEL_DECL)
{
- DECL_ERROR_ISSUED (expr) = (unsigned) bp_unpack_value (bp, 1);
EH_LANDING_PAD_NR (expr) = (int) bp_unpack_var_len_unsigned (bp);
/* Always assume an initial value of -1 for LABEL_DECL_UID to
@@ -258,7 +257,6 @@ unpack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
static void
unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{
- DECL_DEFER_OUTPUT (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_COMMON (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_DLLIMPORT_P (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_WEAK (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -270,11 +268,16 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
if (TREE_CODE (expr) == VAR_DECL)
{
DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1);
- DECL_IN_TEXT_SECTION (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3);
}
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ {
+ DECL_FINAL_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ DECL_CXX_CONSTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ DECL_CXX_DESTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ }
if (VAR_OR_FUNCTION_DECL_P (expr))
{
priority_type p;
@@ -346,7 +349,10 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_NEEDS_CONSTRUCTING (expr) = (unsigned) bp_unpack_value (bp, 1);
if (RECORD_OR_UNION_TYPE_P (expr))
- TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
+ {
+ TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
+ TYPE_FINAL_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ }
else if (TREE_CODE (expr) == ARRAY_TYPE)
TYPE_NONALIASED_COMPONENT (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -923,10 +929,8 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
tree a = stream_read_tree (ib, data_in);
(*BINFO_BASE_ACCESSES (expr))[i] = a;
}
-
- BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in);
- BINFO_SUBVTT_INDEX (expr) = stream_read_tree (ib, data_in);
- BINFO_VPTR_INDEX (expr) = stream_read_tree (ib, data_in);
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index 692a46aae85..98e5cf57785 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -180,7 +180,6 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
/* Note that we do not write LABEL_DECL_UID. The reader will
always assume an initial value of -1 so that the
label_to_block_map is recreated by gimple_set_bb. */
- bp_pack_value (bp, DECL_ERROR_ISSUED (expr), 1);
bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr));
}
@@ -225,7 +224,6 @@ pack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
static void
pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{
- bp_pack_value (bp, DECL_DEFER_OUTPUT (expr), 1);
bp_pack_value (bp, DECL_COMMON (expr), 1);
bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1);
bp_pack_value (bp, DECL_WEAK (expr), 1);
@@ -237,11 +235,17 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
if (TREE_CODE (expr) == VAR_DECL)
{
bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
- bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1);
+ /* DECL_IN_TEXT_SECTION is set during final asm output only. */
bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
bp_pack_value (bp, DECL_TLS_MODEL (expr), 3);
}
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ {
+ bp_pack_value (bp, DECL_FINAL_P (expr), 1);
+ bp_pack_value (bp, DECL_CXX_CONSTRUCTOR_P (expr), 1);
+ bp_pack_value (bp, DECL_CXX_DESTRUCTOR_P (expr), 1);
+ }
if (VAR_OR_FUNCTION_DECL_P (expr))
bp_pack_var_len_unsigned (bp, DECL_INIT_PRIORITY (expr));
}
@@ -293,7 +297,10 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1);
bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
if (RECORD_OR_UNION_TYPE_P (expr))
- bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
+ {
+ bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
+ bp_pack_value (bp, TYPE_FINAL_P (expr), 1);
+ }
else if (TREE_CODE (expr) == ARRAY_TYPE)
bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
bp_pack_value (bp, TYPE_PACKED (expr), 1);
@@ -815,9 +822,8 @@ write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (expr), i, t)
stream_write_tree (ob, t, ref_p);
- stream_write_tree (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p);
- stream_write_tree (ob, BINFO_SUBVTT_INDEX (expr), ref_p);
- stream_write_tree (ob, BINFO_VPTR_INDEX (expr), ref_p);
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 4e99747b73c..7ebdcfe53cf 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -37,7 +37,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-scalar-evolution.h"
#include "tree-vectorizer.h"
#include "diagnostic-core.h"
-
/* Need to include rtl.h, expr.h, etc. for optabs. */
#include "expr.h"
#include "optabs.h"
@@ -255,6 +254,15 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
/* Unknown data dependence. */
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{
+ /* If user asserted safelen consecutive iterations can be
+ executed concurrently, assume independence. */
+ if (loop->safelen >= 2)
+ {
+ if (loop->safelen < *max_vf)
+ *max_vf = loop->safelen;
+ return false;
+ }
+
if (STMT_VINFO_GATHER_P (stmtinfo_a)
|| STMT_VINFO_GATHER_P (stmtinfo_b))
{
@@ -291,6 +299,15 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
/* Known data dependence. */
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
+ /* If user asserted safelen consecutive iterations can be
+ executed concurrently, assume independence. */
+ if (loop->safelen >= 2)
+ {
+ if (loop->safelen < *max_vf)
+ *max_vf = loop->safelen;
+ return false;
+ }
+
if (STMT_VINFO_GATHER_P (stmtinfo_a)
|| STMT_VINFO_GATHER_P (stmtinfo_b))
{
@@ -2254,10 +2271,17 @@ vect_analyze_data_ref_access (struct data_reference *dr)
return false;
}
- /* Allow invariant loads in loops. */
+ /* Allow invariant loads in not nested loops. */
if (loop_vinfo && integer_zerop (step))
{
GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = NULL;
+ if (nested_in_vect_loop_p (loop, stmt))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "zero step in inner loop of nest");
+ return false;
+ }
return DR_IS_READ (dr);
}
@@ -2930,6 +2954,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
stmt_vec_info stmt_info;
tree base, offset, init;
bool gather = false;
+ bool simd_lane_access = false;
int vf;
again:
@@ -2961,12 +2986,17 @@ again:
if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
|| !DR_STEP (dr))
{
- /* If target supports vector gather loads, see if they can't
- be used. */
- if (loop_vinfo
- && DR_IS_READ (dr)
+ bool maybe_gather
+ = DR_IS_READ (dr)
&& !TREE_THIS_VOLATILE (DR_REF (dr))
- && targetm.vectorize.builtin_gather != NULL
+ && targetm.vectorize.builtin_gather != NULL;
+ bool maybe_simd_lane_access
+ = loop_vinfo && loop->simduid;
+
+ /* If target supports vector gather loads, or if this might be
+ a SIMD lane access, see if they can't be used. */
+ if (loop_vinfo
+ && (maybe_gather || maybe_simd_lane_access)
&& !nested_in_vect_loop_p (loop, stmt))
{
struct data_reference *newdr
@@ -2979,14 +3009,59 @@ again:
&& DR_STEP (newdr)
&& integer_zerop (DR_STEP (newdr)))
{
- dr = newdr;
- gather = true;
+ if (maybe_simd_lane_access)
+ {
+ tree off = DR_OFFSET (newdr);
+ STRIP_NOPS (off);
+ if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST
+ && TREE_CODE (off) == MULT_EXPR
+ && host_integerp (TREE_OPERAND (off, 1), 1))
+ {
+ tree step = TREE_OPERAND (off, 1);
+ off = TREE_OPERAND (off, 0);
+ STRIP_NOPS (off);
+ if (CONVERT_EXPR_P (off)
+ && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off,
+ 0)))
+ < TYPE_PRECISION (TREE_TYPE (off)))
+ off = TREE_OPERAND (off, 0);
+ if (TREE_CODE (off) == SSA_NAME)
+ {
+ gimple def = SSA_NAME_DEF_STMT (off);
+ tree reft = TREE_TYPE (DR_REF (newdr));
+ if (gimple_call_internal_p (def)
+ && gimple_call_internal_fn (def)
+ == IFN_GOMP_SIMD_LANE)
+ {
+ tree arg = gimple_call_arg (def, 0);
+ gcc_assert (TREE_CODE (arg) == SSA_NAME);
+ arg = SSA_NAME_VAR (arg);
+ if (arg == loop->simduid
+ /* For now. */
+ && tree_int_cst_equal
+ (TYPE_SIZE_UNIT (reft),
+ step))
+ {
+ DR_OFFSET (newdr) = ssize_int (0);
+ DR_STEP (newdr) = step;
+ dr = newdr;
+ simd_lane_access = true;
+ }
+ }
+ }
+ }
+ }
+ if (!simd_lane_access && maybe_gather)
+ {
+ dr = newdr;
+ gather = true;
+ }
}
- else
+ if (!gather && !simd_lane_access)
free_data_ref (newdr);
}
- if (!gather)
+ if (!gather && !simd_lane_access)
{
if (dump_enabled_p ())
{
@@ -3013,7 +3088,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3046,7 +3121,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3065,7 +3140,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3086,7 +3161,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3221,12 +3296,17 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
STMT_VINFO_DATA_REF (stmt_info) = dr;
+ if (simd_lane_access)
+ {
+ STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) = true;
+ datarefs[i] = dr;
+ }
/* Set vectype for STMT. */
scalar_type = TREE_TYPE (DR_REF (dr));
@@ -3247,7 +3327,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
{
STMT_VINFO_DATA_REF (stmt_info) = NULL;
free_data_ref (dr);
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 12f70ee002a..2bebdeab34c 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -2021,8 +2021,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo,
int bound = 0;
if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "=== vect_do_peeling_for_alignment ===");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "loop peeled for vectorization to enhance"
+ " alignment\n");
initialize_original_copy_tables ();
@@ -2404,6 +2405,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
unsigned prob = 4 * REG_BR_PROB_BASE / 5;
gimple_seq gimplify_stmt_list = NULL;
tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
+ bool version_align = LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo);
+ bool version_alias = LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo);
if (check_profitability)
{
@@ -2413,11 +2416,11 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
is_gimple_condexpr, NULL_TREE);
}
- if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
+ if (version_align)
vect_create_cond_for_align_checks (loop_vinfo, &cond_expr,
&cond_expr_stmt_list);
- if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
+ if (version_alias)
vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr);
cond_expr = force_gimple_operand_1 (cond_expr, &gimplify_stmt_list,
@@ -2427,6 +2430,20 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
initialize_original_copy_tables ();
loop_version (loop, cond_expr, &condition_bb,
prob, prob, REG_BR_PROB_BASE - prob, true);
+
+ if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC
+ && dump_enabled_p ())
+ {
+ if (version_alias)
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "loop versioned for vectorization because of "
+ "possible aliasing\n");
+ if (version_align)
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "loop versioned for vectorization to enhance "
+ "alignment\n");
+
+ }
free_original_copy_tables();
/* Loop versioning violates an assumption we try to maintain during
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 41eac972a97..e8a4ac1643b 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -4373,9 +4373,8 @@ vect_finalize_reduction:
if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
phis.safe_push (USE_STMT (use_p));
- /* We expect to have found an exit_phi because of loop-closed-ssa
- form. */
- gcc_assert (!phis.is_empty ());
+ /* While we expect to have found an exit_phi because of loop-closed-ssa
+ form we can end up without one if the scalar cycle is dead. */
FOR_EACH_VEC_ELT (phis, i, exit_phi)
{
@@ -5378,7 +5377,7 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
bool
vectorizable_live_operation (gimple stmt,
gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
- gimple *vec_stmt ATTRIBUTE_UNUSED)
+ gimple *vec_stmt)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
@@ -5398,7 +5397,41 @@ vectorizable_live_operation (gimple stmt,
return false;
if (!is_gimple_assign (stmt))
- return false;
+ {
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE
+ && gimple_call_lhs (stmt)
+ && loop->simduid
+ && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
+ && loop->simduid
+ == SSA_NAME_VAR (gimple_call_arg (stmt, 0)))
+ {
+ edge e = single_exit (loop);
+ basic_block merge_bb = e->dest;
+ imm_use_iterator imm_iter;
+ use_operand_p use_p;
+ tree lhs = gimple_call_lhs (stmt);
+
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
+ {
+ gimple use_stmt = USE_STMT (use_p);
+ if (gimple_code (use_stmt) == GIMPLE_PHI
+ || gimple_bb (use_stmt) == merge_bb)
+ {
+ if (vec_stmt)
+ {
+ tree vfm1
+ = build_int_cst (unsigned_type_node,
+ loop_vinfo->vectorization_factor - 1);
+ SET_PHI_ARG_DEF (use_stmt, e->dest_idx, vfm1);
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return false;
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 0580f7dfadc..3768dcd114b 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1755,6 +1755,14 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (nargs == 0 || nargs > 3)
return false;
+ /* Ignore the argument of IFN_GOMP_SIMD_LANE, it is magic. */
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
+ {
+ nargs = 0;
+ rhs_type = unsigned_type_node;
+ }
+
for (i = 0; i < nargs; i++)
{
tree opvectype;
@@ -1830,11 +1838,26 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
fndecl = vectorizable_function (stmt, vectype_out, vectype_in);
if (fndecl == NULL_TREE)
{
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "function is not vectorizable.");
-
- return false;
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE
+ && !slp_node
+ && loop_vinfo
+ && LOOP_VINFO_LOOP (loop_vinfo)->simduid
+ && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
+ && LOOP_VINFO_LOOP (loop_vinfo)->simduid
+ == SSA_NAME_VAR (gimple_call_arg (stmt, 0)))
+ {
+ /* We can handle IFN_GOMP_SIMD_LANE by returning a
+ { 0, 1, 2, ... vf - 1 } vector. */
+ gcc_assert (nargs == 0);
+ }
+ else
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "function is not vectorizable.");
+ return false;
+ }
}
gcc_assert (!gimple_vuse (stmt));
@@ -1932,9 +1955,30 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
vargs.quick_push (vec_oprnd0);
}
- new_stmt = gimple_build_call_vec (fndecl, vargs);
- new_temp = make_ssa_name (vec_dest, new_stmt);
- gimple_call_set_lhs (new_stmt, new_temp);
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
+ {
+ tree *v = XALLOCAVEC (tree, nunits_out);
+ int k;
+ for (k = 0; k < nunits_out; ++k)
+ v[k] = build_int_cst (unsigned_type_node, j * nunits_out + k);
+ tree cst = build_vector (vectype_out, v);
+ tree new_var
+ = vect_get_new_vect_var (vectype_out, vect_simple_var, "cst_");
+ gimple init_stmt = gimple_build_assign (new_var, cst);
+ new_temp = make_ssa_name (new_var, init_stmt);
+ gimple_assign_set_lhs (init_stmt, new_temp);
+ vect_init_vector_1 (stmt, init_stmt, NULL);
+ new_temp = make_ssa_name (vec_dest, NULL);
+ new_stmt = gimple_build_assign (new_temp,
+ gimple_assign_lhs (init_stmt));
+ }
+ else
+ {
+ new_stmt = gimple_build_call_vec (fndecl, vargs);
+ new_temp = make_ssa_name (vec_dest, new_stmt);
+ gimple_call_set_lhs (new_stmt, new_temp);
+ }
vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (j == 0)
@@ -3796,6 +3840,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
enum vect_def_type dt;
stmt_vec_info prev_stmt_info = NULL;
tree dataref_ptr = NULL_TREE;
+ tree dataref_offset = NULL_TREE;
gimple ptr_incr = NULL;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies;
@@ -4085,9 +4130,26 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
/* We should have catched mismatched types earlier. */
gcc_assert (useless_type_conversion_p (vectype,
TREE_TYPE (vec_oprnd)));
- dataref_ptr = vect_create_data_ref_ptr (first_stmt, aggr_type, NULL,
- NULL_TREE, &dummy, gsi,
- &ptr_incr, false, &inv_p);
+ bool simd_lane_access_p
+ = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info);
+ if (simd_lane_access_p
+ && TREE_CODE (DR_BASE_ADDRESS (first_dr)) == ADDR_EXPR
+ && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr), 0))
+ && integer_zerop (DR_OFFSET (first_dr))
+ && integer_zerop (DR_INIT (first_dr))
+ && alias_sets_conflict_p (get_alias_set (aggr_type),
+ get_alias_set (DR_REF (first_dr))))
+ {
+ dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr));
+ dataref_offset = build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0);
+ }
+ else
+ dataref_ptr
+ = vect_create_data_ref_ptr (first_stmt, aggr_type,
+ simd_lane_access_p ? loop : NULL,
+ NULL_TREE, &dummy, gsi, &ptr_incr,
+ simd_lane_access_p, &inv_p);
gcc_assert (bb_vinfo || !inv_p);
}
else
@@ -4108,8 +4170,13 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
dr_chain[i] = vec_oprnd;
oprnds[i] = vec_oprnd;
}
- dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
- TYPE_SIZE_UNIT (aggr_type));
+ if (dataref_offset)
+ dataref_offset
+ = int_const_binop (PLUS_EXPR, dataref_offset,
+ TYPE_SIZE_UNIT (aggr_type));
+ else
+ dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
+ TYPE_SIZE_UNIT (aggr_type));
}
if (store_lanes_p)
@@ -4161,8 +4228,10 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
vec_oprnd = result_chain[i];
data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
- build_int_cst (reference_alias_ptr_type
- (DR_REF (first_dr)), 0));
+ dataref_offset
+ ? dataref_offset
+ : build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
align = TYPE_ALIGN_UNIT (vectype);
if (aligned_access_p (first_dr))
misalign = 0;
@@ -4181,8 +4250,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
TYPE_ALIGN (elem_type));
misalign = DR_MISALIGNMENT (first_dr);
}
- set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
- misalign);
+ if (dataref_offset == NULL_TREE)
+ set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
+ misalign);
/* Arguments are ready. Create the new vector stmt. */
new_stmt = gimple_build_assign (data_ref, vec_oprnd);
@@ -4314,6 +4384,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
tree dummy;
enum dr_alignment_support alignment_support_scheme;
tree dataref_ptr = NULL_TREE;
+ tree dataref_offset = NULL_TREE;
gimple ptr_incr = NULL;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies;
@@ -4947,9 +5018,32 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
{
/* 1. Create the vector or array pointer update chain. */
if (j == 0)
- dataref_ptr = vect_create_data_ref_ptr (first_stmt, aggr_type, at_loop,
- offset, &dummy, gsi,
- &ptr_incr, false, &inv_p);
+ {
+ bool simd_lane_access_p
+ = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info);
+ if (simd_lane_access_p
+ && TREE_CODE (DR_BASE_ADDRESS (first_dr)) == ADDR_EXPR
+ && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr), 0))
+ && integer_zerop (DR_OFFSET (first_dr))
+ && integer_zerop (DR_INIT (first_dr))
+ && alias_sets_conflict_p (get_alias_set (aggr_type),
+ get_alias_set (DR_REF (first_dr)))
+ && (alignment_support_scheme == dr_aligned
+ || alignment_support_scheme == dr_unaligned_supported))
+ {
+ dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr));
+ dataref_offset = build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0);
+ }
+ else
+ dataref_ptr
+ = vect_create_data_ref_ptr (first_stmt, aggr_type, at_loop,
+ offset, &dummy, gsi, &ptr_incr,
+ simd_lane_access_p, &inv_p);
+ }
+ else if (dataref_offset)
+ dataref_offset = int_const_binop (PLUS_EXPR, dataref_offset,
+ TYPE_SIZE_UNIT (aggr_type));
else
dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
TYPE_SIZE_UNIT (aggr_type));
@@ -4999,8 +5093,10 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
data_ref
= build2 (MEM_REF, vectype, dataref_ptr,
- build_int_cst (reference_alias_ptr_type
- (DR_REF (first_dr)), 0));
+ dataref_offset
+ ? dataref_offset
+ : build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
align = TYPE_ALIGN_UNIT (vectype);
if (alignment_support_scheme == dr_aligned)
{
@@ -5022,8 +5118,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
TYPE_ALIGN (elem_type));
misalign = DR_MISALIGNMENT (first_dr);
}
- set_ptr_info_alignment (get_ptr_info (dataref_ptr),
- align, misalign);
+ if (dataref_offset == NULL_TREE)
+ set_ptr_info_alignment (get_ptr_info (dataref_ptr),
+ align, misalign);
break;
}
case dr_explicit_realign:
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index cfcc95d06f2..9db94b16673 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -66,13 +66,218 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-vectorizer.h"
#include "tree-pass.h"
+#include "hash-table.h"
+#include "tree-ssa-propagate.h"
/* Loop or bb location. */
LOC vect_location;
/* Vector mapping GIMPLE stmt to stmt_vec_info. */
vec<vec_void_p> stmt_vec_info_vec;
+
+/* For mapping simduid to vectorization factor. */
+
+struct simduid_to_vf : typed_free_remove<simduid_to_vf>
+{
+ unsigned int simduid;
+ int vf;
+
+ /* hash_table support. */
+ typedef simduid_to_vf value_type;
+ typedef simduid_to_vf compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline int equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+simduid_to_vf::hash (const value_type *p)
+{
+ return p->simduid;
+}
+
+inline int
+simduid_to_vf::equal (const value_type *p1, const value_type *p2)
+{
+ return p1->simduid == p2->simduid;
+}
+
+/* This hash maps the OMP simd array to the corresponding simduid used
+ to index into it. Like thus,
+
+ _7 = GOMP_SIMD_LANE (simduid.0)
+ ...
+ ...
+ D.1737[_7] = stuff;
+
+
+ This hash maps from the simduid.0 to OMP simd array (D.1737[]). */
+
+struct simd_array_to_simduid : typed_free_remove<simd_array_to_simduid>
+{
+ tree decl;
+ unsigned int simduid;
+
+ /* hash_table support. */
+ typedef simd_array_to_simduid value_type;
+ typedef simd_array_to_simduid compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline int equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+simd_array_to_simduid::hash (const value_type *p)
+{
+ return DECL_UID (p->decl);
+}
+
+inline int
+simd_array_to_simduid::equal (const value_type *p1, const value_type *p2)
+{
+ return p1->decl == p2->decl;
+}
+
+/* Fold IFN_GOMP_SIMD_LANE, IFN_GOMP_SIMD_VF and IFN_GOMP_SIMD_LAST_LANE
+ into their corresponding constants. */
+
+static void
+adjust_simduid_builtins (hash_table <simduid_to_vf> &htab)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator i;
+
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
+ {
+ unsigned int vf = 1;
+ enum internal_fn ifn;
+ gimple stmt = gsi_stmt (i);
+ tree t;
+ if (!is_gimple_call (stmt)
+ || !gimple_call_internal_p (stmt))
+ continue;
+ ifn = gimple_call_internal_fn (stmt);
+ switch (ifn)
+ {
+ case IFN_GOMP_SIMD_LANE:
+ case IFN_GOMP_SIMD_VF:
+ case IFN_GOMP_SIMD_LAST_LANE:
+ break;
+ default:
+ continue;
+ }
+ tree arg = gimple_call_arg (stmt, 0);
+ gcc_assert (arg != NULL_TREE);
+ gcc_assert (TREE_CODE (arg) == SSA_NAME);
+ simduid_to_vf *p = NULL, data;
+ data.simduid = DECL_UID (SSA_NAME_VAR (arg));
+ if (htab.is_created ())
+ p = htab.find (&data);
+ if (p)
+ vf = p->vf;
+ switch (ifn)
+ {
+ case IFN_GOMP_SIMD_VF:
+ t = build_int_cst (unsigned_type_node, vf);
+ break;
+ case IFN_GOMP_SIMD_LANE:
+ t = build_int_cst (unsigned_type_node, 0);
+ break;
+ case IFN_GOMP_SIMD_LAST_LANE:
+ t = gimple_call_arg (stmt, 1);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ update_call_from_tree (&i, t);
+ }
+ }
+}
+
+/* Helper structure for note_simd_array_uses. */
+
+struct note_simd_array_uses_struct
+{
+ hash_table <simd_array_to_simduid> *htab;
+ unsigned int simduid;
+};
+
+/* Callback for note_simd_array_uses, called through walk_gimple_op. */
+
+static tree
+note_simd_array_uses_cb (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct note_simd_array_uses_struct *ns
+ = (struct note_simd_array_uses_struct *) wi->info;
+
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ else if (VAR_P (*tp)
+ && lookup_attribute ("omp simd array", DECL_ATTRIBUTES (*tp))
+ && DECL_CONTEXT (*tp) == current_function_decl)
+ {
+ simd_array_to_simduid data;
+ if (!ns->htab->is_created ())
+ ns->htab->create (15);
+ data.decl = *tp;
+ data.simduid = ns->simduid;
+ simd_array_to_simduid **slot = ns->htab->find_slot (&data, INSERT);
+ if (*slot == NULL)
+ {
+ simd_array_to_simduid *p = XNEW (simd_array_to_simduid);
+ *p = data;
+ *slot = p;
+ }
+ else if ((*slot)->simduid != ns->simduid)
+ (*slot)->simduid = -1U;
+ *walk_subtrees = 0;
+ }
+ return NULL_TREE;
+}
+
+/* Find "omp simd array" temporaries and map them to corresponding
+ simduid. */
+
+static void
+note_simd_array_uses (hash_table <simd_array_to_simduid> *htab)
+{
+ basic_block bb;
+ gimple_stmt_iterator gsi;
+ struct walk_stmt_info wi;
+ struct note_simd_array_uses_struct ns;
+
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &ns;
+ ns.htab = htab;
+ FOR_EACH_BB (bb)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (!is_gimple_call (stmt) || !gimple_call_internal_p (stmt))
+ continue;
+ switch (gimple_call_internal_fn (stmt))
+ {
+ case IFN_GOMP_SIMD_LANE:
+ case IFN_GOMP_SIMD_VF:
+ case IFN_GOMP_SIMD_LAST_LANE:
+ break;
+ default:
+ continue;
+ }
+ tree lhs = gimple_call_lhs (stmt);
+ if (lhs == NULL_TREE)
+ continue;
+ imm_use_iterator use_iter;
+ gimple use_stmt;
+ ns.simduid = DECL_UID (SSA_NAME_VAR (gimple_call_arg (stmt, 0)));
+ FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, lhs)
+ if (!is_gimple_debug (use_stmt))
+ walk_gimple_op (use_stmt, note_simd_array_uses_cb, &wi);
+ }
+}
/* Function vectorize_loops.
@@ -86,12 +291,21 @@ vectorize_loops (void)
unsigned int vect_loops_num;
loop_iterator li;
struct loop *loop;
+ hash_table <simduid_to_vf> simduid_to_vf_htab;
+ hash_table <simd_array_to_simduid> simd_array_to_simduid_htab;
vect_loops_num = number_of_loops (cfun);
/* Bail out if there are no loops. */
if (vect_loops_num <= 1)
- return 0;
+ {
+ if (cfun->has_simduid_loops)
+ adjust_simduid_builtins (simduid_to_vf_htab);
+ return 0;
+ }
+
+ if (cfun->has_simduid_loops)
+ note_simd_array_uses (&simd_array_to_simduid_htab);
init_stmt_vec_info_vec ();
@@ -101,7 +315,8 @@ vectorize_loops (void)
than all previously defined loops. This fact allows us to run
only over initial loops skipping newly generated ones. */
FOR_EACH_LOOP (li, loop, 0)
- if (optimize_loop_nest_for_speed_p (loop))
+ if ((flag_tree_vectorize && optimize_loop_nest_for_speed_p (loop))
+ || loop->force_vect)
{
loop_vec_info loop_vinfo;
vect_location = find_loop_location (loop);
@@ -119,9 +334,23 @@ vectorize_loops (void)
if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC
&& dump_enabled_p ())
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
- "Vectorized loop\n");
+ "loop vectorized\n");
vect_transform_loop (loop_vinfo);
num_vectorized_loops++;
+ /* Now that the loop has been vectorized, allow it to be unrolled
+ etc. */
+ loop->force_vect = false;
+
+ if (loop->simduid)
+ {
+ simduid_to_vf *simduid_to_vf_data = XNEW (simduid_to_vf);
+ if (!simduid_to_vf_htab.is_created ())
+ simduid_to_vf_htab.create (15);
+ simduid_to_vf_data->simduid = DECL_UID (loop->simduid);
+ simduid_to_vf_data->vf = loop_vinfo->vectorization_factor;
+ *simduid_to_vf_htab.find_slot (simduid_to_vf_data, INSERT)
+ = simduid_to_vf_data;
+ }
}
vect_location = UNKNOWN_LOC;
@@ -149,6 +378,40 @@ vectorize_loops (void)
free_stmt_vec_info_vec ();
+ /* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */
+ if (cfun->has_simduid_loops)
+ adjust_simduid_builtins (simduid_to_vf_htab);
+
+ /* Shrink any "omp array simd" temporary arrays to the
+ actual vectorization factors. */
+ if (simd_array_to_simduid_htab.is_created ())
+ {
+ for (hash_table <simd_array_to_simduid>::iterator iter
+ = simd_array_to_simduid_htab.begin ();
+ iter != simd_array_to_simduid_htab.end (); ++iter)
+ if ((*iter).simduid != -1U)
+ {
+ tree decl = (*iter).decl;
+ int vf = 1;
+ if (simduid_to_vf_htab.is_created ())
+ {
+ simduid_to_vf *p = NULL, data;
+ data.simduid = (*iter).simduid;
+ p = simduid_to_vf_htab.find (&data);
+ if (p)
+ vf = p->vf;
+ }
+ tree atype
+ = build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf);
+ TREE_TYPE (decl) = atype;
+ relayout_decl (decl);
+ }
+
+ simd_array_to_simduid_htab.dispose ();
+ }
+ if (simduid_to_vf_htab.is_created ())
+ simduid_to_vf_htab.dispose ();
+
if (num_vectorized_loops > 0)
{
/* If we vectorized any loop only virtual SSA form needs to be updated.
@@ -180,7 +443,7 @@ execute_vect_slp (void)
vect_slp_transform_bb (bb);
if (dump_enabled_p ())
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
- "Vectorized basic-block\n");
+ "basic block vectorized\n");
}
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 7c5dfe884df..3570dc9d76a 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -576,6 +576,9 @@ typedef struct _stmt_vec_info {
/* For loads only, true if this is a gather load. */
bool gather_p;
bool stride_load_p;
+
+ /* For both loads and stores. */
+ bool simd_lane_access_p;
} *stmt_vec_info;
/* Access Functions. */
@@ -591,6 +594,7 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_DATA_REF(S) (S)->data_ref_info
#define STMT_VINFO_GATHER_P(S) (S)->gather_p
#define STMT_VINFO_STRIDE_LOAD_P(S) (S)->stride_load_p
+#define STMT_VINFO_SIMD_LANE_ACCESS_P(S) (S)->simd_lane_access_p
#define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address
#define STMT_VINFO_DR_INIT(S) (S)->dr_init
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 48b9f7a072c..d5548ff55eb 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -5410,10 +5410,14 @@ register_edge_assert_for_1 (tree op, enum tree_code code,
&& gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))
{
/* Recurse on each operand. */
- retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
- code, e, bsi);
- retval |= register_edge_assert_for_1 (gimple_assign_rhs2 (op_def),
- code, e, bsi);
+ tree op0 = gimple_assign_rhs1 (op_def);
+ tree op1 = gimple_assign_rhs2 (op_def);
+ if (TREE_CODE (op0) == SSA_NAME
+ && has_single_use (op0))
+ retval |= register_edge_assert_for_1 (op0, code, e, bsi);
+ if (TREE_CODE (op1) == SSA_NAME
+ && has_single_use (op1))
+ retval |= register_edge_assert_for_1 (op1, code, e, bsi);
}
else if (gimple_assign_rhs_code (op_def) == BIT_NOT_EXPR
&& TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (op_def))) == 1)
diff --git a/gcc/tree.c b/gcc/tree.c
index 24779a6ba95..b469b97c867 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -236,6 +236,8 @@ unsigned const char omp_clause_num_ops[] =
4, /* OMP_CLAUSE_REDUCTION */
1, /* OMP_CLAUSE_COPYIN */
1, /* OMP_CLAUSE_COPYPRIVATE */
+ 2, /* OMP_CLAUSE_LINEAR */
+ 1, /* OMP_CLAUSE_UNIFORM */
1, /* OMP_CLAUSE_IF */
1, /* OMP_CLAUSE_NUM_THREADS */
1, /* OMP_CLAUSE_SCHEDULE */
@@ -245,7 +247,9 @@ unsigned const char omp_clause_num_ops[] =
3, /* OMP_CLAUSE_COLLAPSE */
0, /* OMP_CLAUSE_UNTIED */
1, /* OMP_CLAUSE_FINAL */
- 0 /* OMP_CLAUSE_MERGEABLE */
+ 0, /* OMP_CLAUSE_MERGEABLE */
+ 1, /* OMP_CLAUSE_SAFELEN */
+ 1, /* OMP_CLAUSE__SIMDUID_ */
};
const char * const omp_clause_code_name[] =
@@ -258,6 +262,8 @@ const char * const omp_clause_code_name[] =
"reduction",
"copyin",
"copyprivate",
+ "linear",
+ "uniform",
"if",
"num_threads",
"schedule",
@@ -267,7 +273,9 @@ const char * const omp_clause_code_name[] =
"collapse",
"untied",
"final",
- "mergeable"
+ "mergeable",
+ "safelen",
+ "_simduid_"
};
@@ -9788,7 +9796,10 @@ build_common_tree_nodes (bool signed_char, bool short_double)
}
}
-/* Modify DECL for given flags. */
+/* Modify DECL for given flags.
+ TM_PURE attribute is set only on types, so the function will modify
+ DECL's type when ECF_TM_PURE is used. */
+
void
set_call_expr_flags (tree decl, int flags)
{
@@ -9812,8 +9823,7 @@ set_call_expr_flags (tree decl, int flags)
DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
NULL, DECL_ATTRIBUTES (decl));
if ((flags & ECF_TM_PURE) && flag_tm)
- DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("transaction_pure"),
- NULL, DECL_ATTRIBUTES (decl));
+ apply_tm_attr (decl, get_identifier ("transaction_pure"));
/* Looping const or pure is implied by noreturn.
There is currently no way to declare looping const or looping pure alone. */
gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE)
@@ -11066,6 +11076,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
case OMP_CLAUSE_IF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_SCHEDULE:
+ case OMP_CLAUSE_UNIFORM:
+ case OMP_CLAUSE_SAFELEN:
+ case OMP_CLAUSE__SIMDUID_:
WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
/* FALLTHRU */
@@ -11089,6 +11102,11 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
}
+ case OMP_CLAUSE_LINEAR:
+ WALK_SUBTREE (OMP_CLAUSE_DECL (*tp));
+ WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1));
+ WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+
case OMP_CLAUSE_REDUCTION:
{
int i;
diff --git a/gcc/tree.def b/gcc/tree.def
index da30074b109..f825aad5355 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1030,6 +1030,10 @@ DEFTREECODE (OMP_TASK, "omp_task", tcc_statement, 2)
unspecified by the standard. */
DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6)
+/* OpenMP - #pragma omp simd [clause1 ... clauseN]
+ Operands like for OMP_FOR. */
+DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6)
+
/* OpenMP - #pragma omp sections [clause1 ... clauseN]
Operand 0: OMP_SECTIONS_BODY: Sections body.
Operand 1: OMP_SECTIONS_CLAUSES: List of clauses. */
diff --git a/gcc/tree.h b/gcc/tree.h
index 063e302bb95..83edabaeff9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -365,6 +365,12 @@ enum omp_clause_code
/* OpenMP clause: copyprivate (variable_list). */
OMP_CLAUSE_COPYPRIVATE,
+ /* OpenMP clause: linear (variable-list[:linear-step]). */
+ OMP_CLAUSE_LINEAR,
+
+ /* OpenMP clause: uniform (argument-list). */
+ OMP_CLAUSE_UNIFORM,
+
/* OpenMP clause: if (scalar-expression). */
OMP_CLAUSE_IF,
@@ -393,7 +399,13 @@ enum omp_clause_code
OMP_CLAUSE_FINAL,
/* OpenMP clause: mergeable. */
- OMP_CLAUSE_MERGEABLE
+ OMP_CLAUSE_MERGEABLE,
+
+ /* OpenMP clause: safelen (constant-integer-expression). */
+ OMP_CLAUSE_SAFELEN,
+
+ /* Internally used only clause, holding SIMD uid. */
+ OMP_CLAUSE__SIMDUID_
};
/* The definition of tree nodes fills the next several pages. */
@@ -560,6 +572,9 @@ struct GTY(()) tree_base {
OMP_CLAUSE_PRIVATE_DEBUG in
OMP_CLAUSE_PRIVATE
+ OMP_CLAUSE_LINEAR_NO_COPYIN in
+ OMP_CLAUSE_LINEAR
+
TRANSACTION_EXPR_RELAXED in
TRANSACTION_EXPR
@@ -580,6 +595,9 @@ struct GTY(()) tree_base {
OMP_CLAUSE_PRIVATE_OUTER_REF in
OMP_CLAUSE_PRIVATE
+ OMP_CLAUSE_LINEAR_NO_COPYOUT in
+ OMP_CLAUSE_LINEAR
+
TYPE_REF_IS_RVALUE in
REFERENCE_TYPE
@@ -1803,7 +1821,7 @@ extern void protected_set_expr_location (tree, location_t);
#define OMP_CLAUSE_DECL(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
OMP_CLAUSE_PRIVATE, \
- OMP_CLAUSE_COPYPRIVATE), 0)
+ OMP_CLAUSE_UNIFORM), 0)
#define OMP_CLAUSE_HAS_LOCATION(NODE) \
(LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \
!= UNKNOWN_LOCATION)
@@ -1870,6 +1888,25 @@ extern void protected_set_expr_location (tree, location_t);
#define OMP_CLAUSE_REDUCTION_PLACEHOLDER(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 3)
+/* True if a LINEAR clause doesn't need copy in. True for iterator vars which
+ are always initialized inside of the loop construct, false otherwise. */
+#define OMP_CLAUSE_LINEAR_NO_COPYIN(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR)->base.public_flag)
+
+/* True if a LINEAR clause doesn't need copy out. True for iterator vars which
+ are declared inside of the simd construct. */
+#define OMP_CLAUSE_LINEAR_NO_COPYOUT(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR))
+
+#define OMP_CLAUSE_LINEAR_STEP(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 1)
+
+#define OMP_CLAUSE_SAFELEN_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SAFELEN), 0)
+
+#define OMP_CLAUSE__SIMDUID__DECL(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SIMDUID_), 0)
+
enum omp_clause_schedule_kind
{
OMP_CLAUSE_SCHEDULE_STATIC,
@@ -2843,8 +2880,7 @@ struct GTY(()) tree_decl_common {
unsigned lang_flag_7 : 1;
unsigned lang_flag_8 : 1;
- /* In LABEL_DECL, this is DECL_ERROR_ISSUED.
- In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */
+ /* In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */
unsigned decl_flag_0 : 1;
/* In FIELD_DECL, this is DECL_BIT_FIELD
In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL.
@@ -3036,11 +3072,6 @@ struct GTY(()) tree_field_decl {
#define EH_LANDING_PAD_NR(NODE) \
(LABEL_DECL_CHECK (NODE)->label_decl.eh_landing_pad_nr)
-/* In LABEL_DECL nodes, nonzero means that an error message about
- jumping into such a binding contour has been printed for this label. */
-#define DECL_ERROR_ISSUED(NODE) \
- (LABEL_DECL_CHECK (NODE)->decl_common.decl_flag_0)
-
struct GTY(()) tree_label_decl {
struct tree_decl_with_rtl common;
int label_decl_uid;
@@ -4815,6 +4846,7 @@ extern tree build_translation_unit_decl (tree);
extern tree build_block (tree, tree, tree, tree);
extern tree build_empty_stmt (location_t);
extern tree build_omp_clause (location_t, enum omp_clause_code);
+extern tree find_omp_clause (tree, enum omp_clause_code);
extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
#define build_vl_exp(c,n) build_vl_exp_stat (c,n MEM_STAT_INFO)
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 69fcbbcf41d..3aa5c7469ee 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -585,9 +585,11 @@ check_counter (gimple stmt, const char * name,
: DECL_SOURCE_LOCATION (current_function_decl);
if (flag_profile_correction)
{
- inform (locus, "correcting inconsistent value profile: "
- "%s profiler overall count (%d) does not match BB count "
- "(%d)", name, (int)*all, (int)bb_count);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
+ "correcting inconsistent value profile: %s "
+ "profiler overall count (%d) does not match BB "
+ "count (%d)", name, (int)*all, (int)bb_count);
*all = bb_count;
if (*count > *all)
*count = *all;
@@ -1271,8 +1273,10 @@ check_ic_target (gimple call_stmt, struct cgraph_node *target)
return true;
locus = gimple_location (call_stmt);
- inform (locus, "Skipping target %s with mismatching types for icall ",
- cgraph_node_name (target));
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
+ "Skipping target %s with mismatching types for icall ",
+ cgraph_node_name (target));
return false;
}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 866156686d3..90f68ae86be 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,21 @@
+2013-08-29 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex.h (basic_regex<>::assign): Don't lose _M_traits.
+ (regex_iterator<>::regex_iterator): Return nullptr when regex_search
+ failed.
+ (regex_token_iterator<>::_M_end_of_seq): Should be defined true when
+ _M_result is(not isn't) nullptr.
+ * include/bits/regex_compiler.h: Store _Compiler::_M_traits by reference
+ instead of by value.
+ * include/bits/regex_executor.h (_DFSExecutor<>::_DFSExecutor): Add
+ _M_traits to _DFSExecutor.
+ * include/bits/regex_executor.tcc (__get_executor<>): Pass traits to
+ _DFSExecutor too.
+ * testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc:
+ New.
+ * testsuite/28_regex/iterators/regex_token_iterator/wchar_t/
+ wstring_02.cc: New.
+
2013-08-26 Tim Shen <timshen91@gmail.com>
* include/Makefile.am: Add regex_scanner.{h,tcc}.
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 48388198ce0..412465adfa2 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -880,8 +880,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
assign(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s,
flag_type __flags = ECMAScript)
{
- basic_regex __tmp(__s, __flags);
- this->swap(__tmp);
+ _M_flags = __flags;
+ _M_automaton =
+ __detail::_Compiler<decltype(__s.begin()), _Ch_type, _Rx_traits>
+ (__s.begin(), __s.end(), _M_traits, _M_flags)._M_get_nfa();
return *this;
}
@@ -2591,7 +2593,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
regex_constants::match_flag_type __m
= regex_constants::match_default)
: _M_begin(__a), _M_end(__b), _M_pregex(&__re), _M_flags(__m), _M_match()
- { regex_search(_M_begin, _M_end, _M_match, *_M_pregex, _M_flags); }
+ {
+ if (!regex_search(_M_begin, _M_end, _M_match, *_M_pregex, _M_flags))
+ *this = regex_iterator();
+ }
/**
* Copy constructs a %regex_iterator.
@@ -2905,9 +2910,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return (*_M_position)[_M_subs[_M_n]];
}
- bool
- _M_end_of_seq() const
- { return _M_result != nullptr; }
+ constexpr bool
+ _M_end_of_seq()
+ { return _M_result == nullptr; }
_Position _M_position;
const value_type* _M_result;
diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h
index 1d588b91df8..a1107bb7eeb 100644
--- a/libstdc++-v3/include/bits/regex_compiler.h
+++ b/libstdc++-v3/include/bits/regex_compiler.h
@@ -214,7 +214,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return _M_traits.transform(__s.begin(), __s.end());
}
- _TraitsT _M_traits;
+ const _TraitsT& _M_traits;
_FlagT _M_flags;
bool _M_is_non_matching;
std::vector<_CharT> _M_char_set;
diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h
index 23998ed064d..6d66d881584 100644
--- a/libstdc++-v3/include/bits/regex_executor.h
+++ b/libstdc++-v3/include/bits/regex_executor.h
@@ -120,13 +120,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename _BaseT::_ResultsVec _ResultsVec;
typedef regex_constants::match_flag_type _FlagT;
- _DFSExecutor(_BiIter __begin,
- _BiIter __end,
- _ResultsT& __results,
- const _RegexT& __nfa,
- _FlagT __flags)
+ _DFSExecutor(_BiIter __begin,
+ _BiIter __end,
+ _ResultsT& __results,
+ const _RegexT& __nfa,
+ const _TraitsT& __traits,
+ _FlagT __flags)
: _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()),
- _M_traits(_TraitsT()), _M_nfa(__nfa), _M_results_ret(this->_M_results)
+ _M_traits(__traits), _M_nfa(__nfa), _M_results_ret(this->_M_results)
{ }
void
@@ -142,9 +143,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
_M_dfs(_StateIdT __i);
- _ResultsVec _M_results_ret;
- _TraitsT _M_traits;
- const _RegexT& _M_nfa;
+ _ResultsVec _M_results_ret;
+ const _TraitsT& _M_traits;
+ const _RegexT& _M_nfa;
};
// Like the DFS approach, it try every possible state transition; Unlike DFS,
diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc
index edfd0b649ff..788d65e54de 100644
--- a/libstdc++-v3/include/bits/regex_executor.tcc
+++ b/libstdc++-v3/include/bits/regex_executor.tcc
@@ -320,7 +320,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto __p = std::static_pointer_cast<_NFA<_CharT, _TraitsT>>
(__re._M_automaton);
if (__p->_M_has_backref)
- return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p, __flags));
+ return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p,
+ __re._M_traits, __flags));
return _ExecutorPtr(new _BFSExecutorT(__b, __e, __m, *__p, __flags));
}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc
new file mode 100644
index 00000000000..6ab48ca6baf
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-namedlocale "de_DE.UTF-8" }
+
+//
+// 2013-08-29 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests Extended localization against a wide-string.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::wstring str2 = L"ÜBER";
+ std::wregex re2;
+ re2.imbue(std::locale("de_DE.UTF-8"));
+ re2.assign(L"[[:upper:]]*", std::regex::extended);
+ std::wsmatch m2;
+ VERIFY(std::regex_match(str2, m2, re2));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc
new file mode 100644
index 00000000000..0306ee197b9
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-namedlocale "en_US.UTF-8" }
+
+//
+// 2013-08-29 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.12.2 regex_token_iterator
+// Tests regex_token_iterator class over a localized wstring.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::setlocale(LC_ALL, "en_US.UTF-8");
+
+ std::wstring str2 = L"öäü";
+ std::wregex re2;
+ re2.assign(L"([[:lower:]]+)");
+ std::wsmatch m2;
+
+ std::wsregex_token_iterator end {};
+ std::wsregex_token_iterator p{str2.begin(), str2.end(), re2, {1}};
+
+ VERIFY(p == end);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog
index d05a8e7b4fe..c9a1cc3590e 100644
--- a/libvtv/ChangeLog
+++ b/libvtv/ChangeLog
@@ -1,3 +1,19 @@
+2013-08-20 Caroline Tice <cmtice@google.com>
+
+ * Makefile.am (DEFS): Add "@DEFS@", to inherit defintions.
+ * Makefile.in: Regenerate.
+ * configure.ac: Add check for __secure_getenv and secure_getenv.
+ * configure: Regenerate.
+ * vtv_utils.cc : Include stdlib.h
+ (HAVE_SECURE_GETENV): Add checks and definitions for secure_getenv.
+ (log_dirs): Remove file static constant.
+ (__vtv_open_log): Increase size of log file name. Add the user
+ and process ids to the file name. Do not put the log files in /tmp.
+ Instead try to get the directory name from an environment variable; if
+ that fails try to use stderr. Add O_NOFOLLOW to the flags
+ for 'open'. Update function comment.
+ * vtv_rts.cc (log_memory_protection_data): Remove %d from file name.
+
2013-08-08 Benjamin Kosnik <bkoz@rehat.com>
Michael Meissner <meissner@linux.vnet.ibm.com>
@@ -12,6 +28,9 @@
* configure: Regenerate.
2013-08-02 Caroline Tice <cmtice@google.com>
+ Benjamin Kosnik <bkoz@redhat.com>
+ Luis Lozano <llozano@google.com>
+ Geoff Pike <gpike@google.com>
Initial check-in of new vtable verification feature.
* configure.ac : New file.