On Tue, Jan 19, 2016 at 10:08:17AM +0100, Richard Biener wrote:
>
> The following patch enhances the recent change to DOMs memory reference
> value-numbering to cover PR69336 (all handled components instead of
> just ones with outermost ARRAY_REF).
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
The new test case fails on s390x:
-- snip --
void * D.35681;
size_t n;
const struct static_map cmap;
const char * _4;
int _5;
int _11;
void * _15;
int _25;
:
cmap = *.LC3;
_5 = cmap._values[0].second.first;
if (_5 == 8)
goto ;
else
goto ;
:
_25 = cmap._values[1].second.first;
if (_25 == 8)
goto ;
else
goto ;
:
_11 = cmap._values[2].second.first;
if (_11 == 8)
goto ;
else
goto ;
:
# n_8 = PHI <2(4), 0(2), 1(3)>
_4 = MEM[(const char * const &)&cmap]._values[n_8].second.second;
if (_4 == 0B)
goto ;
else
goto ;
:
_15 = __cxa_allocate_exception (16);
std::out_of_range::out_of_range (_15, "Key not found");
:
__cxa_throw (_15, &_ZTISt12out_of_range, __comp_dtor );
:
__cxa_free_exception (_15);
_3 = __builtin_eh_pointer (5);
__builtin_unwind_resume (_3);
:
abort ();
:
cmap ={v} {CLOBBER};
return 0;
-- snip --
> 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.
>
> Index: gcc/tree-ssa-scopedtables.c
> ===
> *** gcc/tree-ssa-scopedtables.c (revision 232508)
> --- gcc/tree-ssa-scopedtables.c (working copy)
> *** avail_expr_hash (class expr_hash_elt *p)
> *** 214,220
> {
> /* 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)
> {
> /* Make equivalent statements of both these kinds hash together.
>Dealing with both MEM_REF and ARRAY_REF allows us not to care
> --- 214,220
> {
> /* T could potentially be a switch index or a goto dest. */
> tree t = expr->ops.single.rhs;
> ! 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
> *** avail_expr_hash (class expr_hash_elt *p)
> *** 251,259
> static bool
> equal_mem_array_ref_p (tree t0, tree t1)
> {
> ! if (TREE_CODE (t0) != MEM_REF && TREE_CODE (t0) != ARRAY_REF)
> return false;
> ! if (TREE_CODE (t1) != MEM_REF && TREE_CODE (t1) != ARRAY_REF)
> return false;
>
> if (!types_compatible_p (TREE_TYPE (t0), TREE_TYPE (t1)))
> --- 251,259
> static bool
> equal_mem_array_ref_p (tree t0, tree t1)
> {
> ! if (TREE_CODE (t0) != MEM_REF && ! handled_component_p (t0))
> return false;
> ! if (TREE_CODE (t1) != MEM_REF && ! handled_component_p (t1))
> return false;
>
> if (!types_compatible_p (TREE_TYPE (t0), TREE_TYPE (t1)))
> Index: gcc/testsuite/g++.dg/tree-ssa/pr69336.C
> ===
> *** gcc/testsuite/g++.dg/tree-ssa/pr69336.C (revision 0)
> --- gcc/testsuite/g++.dg/tree-ssa/pr69336.C (working copy)
> ***
> *** 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)
> + {
> + retur