Commit 879c27e3 by Richard Biener Committed by Richard Biener

re PR tree-optimization/69336 (Constant value not detected)

2016-01-19  Richard Biener  <rguenther@suse.de>

	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.

From-SVN: r232559
parent 015337d3
2016-01-19 Richard Biener <rguenther@suse.de>
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 <jakub@redhat.com>
PR debug/65779
......
2016-01-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/69336
* g++.dg/tree-ssa/pr69336.C: New testcase.
2016-01-19 Jakub Jelinek <jakub@redhat.com>
PR debug/65779
......
// { dg-do compile }
// { dg-options "-O3 -fdump-tree-optimized -std=c++14" }
#include <array>
#include <utility>
template<class Key, class T, size_t N> struct static_map
{
using key_type = Key;
using mapped_type = T;
using value_type = std::pair<const key_type, mapped_type>;
private:
using _value_type = std::pair<size_t, value_type>;
_value_type _values[N];
static constexpr _value_type _new_value_type(const std::pair<Key, T> &v)
{
return std::make_pair(0, std::make_pair(v.first, v.second));
}
public:
template<class... U> 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<class Key, class T, size_t N, size_t... I> constexpr static_map<Key, T, N> static_map_from_array(const std::pair<Key, T>(&il)[N], std::index_sequence<I...>)
{
return static_map<Key, T, N>(il[I]...);
}
}
template<class Key, class T, size_t N> constexpr static_map<Key, T, N> make_static_map(const std::pair<Key, T> (&il)[N])
{
return detail::static_map_from_array<Key, T, N>(il, std::make_index_sequence<N>());
}
/* Two phase construction, required because heterogeneous braced init
in C++ 14 has a big limitation: template<class... Args> 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<const int, const char *> map_data[] = {
{ 5, "apple" },
{ 8, "pear" },
{ 0, "banana" }
};
template<size_t N> 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" } }
......@@ -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)))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment