From: rguenth Date: Tue, 19 Jan 2016 13:27:11 +0000 (+0000) Subject: 2016-01-19 Richard Biener X-Git-Tag: upstream/6.1~1637 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dc5d6d17a8d8aeb0b57f90a73aee2e59afb6006b;p=platform%2Fupstream%2Flinaro-gcc.git 2016-01-19 Richard Biener PR tree-optimization/69336 * tree-ssa-scopedtables.c (avail_expr_hash): Handle all handled components with get_ref_base_and_extent. (equal_mem_array_ref_p): Adjust. * g++.dg/tree-ssa/pr69336.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232559 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dfc2174..a4a9047 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-01-19 Richard Biener + + PR tree-optimization/69336 + * tree-ssa-scopedtables.c (avail_expr_hash): Handle all + handled components with get_ref_base_and_extent. + (equal_mem_array_ref_p): Adjust. + 2016-01-19 Jakub Jelinek PR debug/65779 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c0dfcf1..9f48678 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-19 Richard Biener + + PR tree-optimization/69336 + * g++.dg/tree-ssa/pr69336.C: New testcase. + 2016-01-19 Jakub Jelinek PR debug/65779 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr69336.C b/gcc/testsuite/g++.dg/tree-ssa/pr69336.C new file mode 100644 index 0000000..67f87cf --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr69336.C @@ -0,0 +1,86 @@ +// { dg-do compile } +// { dg-options "-O3 -fdump-tree-optimized -std=c++14" } + +#include +#include + + +template struct static_map +{ + using key_type = Key; + using mapped_type = T; + using value_type = std::pair; +private: + using _value_type = std::pair; + _value_type _values[N]; + static constexpr _value_type _new_value_type(const std::pair &v) + { + return std::make_pair(0, std::make_pair(v.first, v.second)); + } +public: + template constexpr static_map(U &&...il) : _values{ _new_value_type(il)... } { } + constexpr mapped_type &operator[](const key_type &k) { return at(k); } + constexpr const mapped_type &operator[](const key_type &k) const { return at(k); } + constexpr mapped_type &at(const key_type &k) + { + for (size_t n = 0; n < N; n++) + if (_values[n].second.first == k) + return _values[n].second.second; + throw std::out_of_range("Key not found"); + } + constexpr const mapped_type &at(const key_type &k) const + { + for (size_t n = 0; n < N; n++) + if (_values[n].second.first == k) + return _values[n].second.second; + throw std::out_of_range("Key not found"); + } +}; +namespace detail +{ + template constexpr static_map static_map_from_array(const std::pair(&il)[N], std::index_sequence) + { + return static_map(il[I]...); + } +} +template constexpr static_map make_static_map(const std::pair (&il)[N]) +{ + return detail::static_map_from_array(il, std::make_index_sequence()); +} + +/* Two phase construction, required because heterogeneous braced init +in C++ 14 has a big limitation: template auto make(Args &&...) +will accept make({ 5, "apple" }) as make(int, const char *) but +make({ 5, "apple" }, { 8, "pear" }) will fail to deduce Args as a +heterogeneous initializer_list is not permitted. This forces something +like make(make_pair{ 5, "apple" }, make_pair{ 8, "pear" }, ...) which +is less succinct than using a constexpr C array for the nested braced init. +*/ +constexpr std::pair map_data[] = { + { 5, "apple" }, + { 8, "pear" }, + { 0, "banana" } +}; + +template constexpr int cstrcmp(const char *a, const char *b) +{ + for (size_t n = 0; n < N; n++) + { + if (a[n] < b[n]) return -1; + if (a[n] > b[n]) return 1; + } + return 0; +} + +int main(void) +{ + constexpr auto cmap = make_static_map(map_data); + // No abort() appears in assembler, so this was executed constexpr + if(!cmap[8]) abort(); + // This however does cause code implementing a lookup to be generated, + // so this was NOT executed constexpr + //const char *foo=cmap[5]; + return 0; +} + +// { dg-final { scan-tree-dump-not "cmap" "optimized" } } diff --git a/gcc/tree-ssa-scopedtables.c b/gcc/tree-ssa-scopedtables.c index c421f43..613f50b 100644 --- a/gcc/tree-ssa-scopedtables.c +++ b/gcc/tree-ssa-scopedtables.c @@ -214,7 +214,7 @@ avail_expr_hash (class expr_hash_elt *p) { /* T could potentially be a switch index or a goto dest. */ tree t = expr->ops.single.rhs; - if (TREE_CODE (t) == MEM_REF || TREE_CODE (t) == ARRAY_REF) + if (TREE_CODE (t) == MEM_REF || handled_component_p (t)) { /* Make equivalent statements of both these kinds hash together. Dealing with both MEM_REF and ARRAY_REF allows us not to care @@ -252,9 +252,9 @@ avail_expr_hash (class expr_hash_elt *p) static bool equal_mem_array_ref_p (tree t0, tree t1) { - if (TREE_CODE (t0) != MEM_REF && TREE_CODE (t0) != ARRAY_REF) + if (TREE_CODE (t0) != MEM_REF && ! handled_component_p (t0)) return false; - if (TREE_CODE (t1) != MEM_REF && TREE_CODE (t1) != ARRAY_REF) + if (TREE_CODE (t1) != MEM_REF && ! handled_component_p (t1)) return false; if (!types_compatible_p (TREE_TYPE (t0), TREE_TYPE (t1)))