1 /* Support routines for value queries.
2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew MacLeod <amacleod@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
29 #include "tree-pretty-print.h"
30 #include "fold-const.h"
31 #include "value-range-equiv.h"
32 #include "value-query.h"
33 #include "alloc-pool.h"
35 // value_query default methods.
38 value_query::value_on_edge (edge
, tree name
)
40 return value_of_expr (name
);
44 value_query::value_of_stmt (gimple
*stmt
, tree name
)
47 name
= gimple_get_lhs (stmt
);
49 gcc_checking_assert (!name
|| name
== gimple_get_lhs (stmt
));
52 return value_of_expr (name
);
56 // range_query default methods.
59 range_query::range_on_edge (irange
&r
, edge
, tree name
)
61 return range_of_expr (r
, name
);
65 range_query::range_of_stmt (irange
&r
, gimple
*stmt
, tree name
)
68 name
= gimple_get_lhs (stmt
);
70 gcc_checking_assert (!name
|| name
== gimple_get_lhs (stmt
));
73 return range_of_expr (r
, name
);
78 range_query::value_of_expr (tree name
, gimple
*stmt
)
83 if (!irange::supports_type_p (TREE_TYPE (name
)))
86 if (range_of_expr (r
, name
, stmt
))
88 // A constant used in an unreachable block oftens returns as UNDEFINED.
89 // If the result is undefined, check the global value for a constant.
91 range_of_expr (r
, name
);
92 if (r
.singleton_p (&t
))
99 range_query::value_on_edge (edge e
, tree name
)
104 if (!irange::supports_type_p (TREE_TYPE (name
)))
106 if (range_on_edge (r
, e
, name
))
108 // A constant used in an unreachable block oftens returns as UNDEFINED.
109 // If the result is undefined, check the global value for a constant.
110 if (r
.undefined_p ())
111 range_of_expr (r
, name
);
112 if (r
.singleton_p (&t
))
120 range_query::value_of_stmt (gimple
*stmt
, tree name
)
126 name
= gimple_get_lhs (stmt
);
128 gcc_checking_assert (!name
|| name
== gimple_get_lhs (stmt
));
130 if (!name
|| !irange::supports_type_p (TREE_TYPE (name
)))
132 if (range_of_stmt (r
, stmt
, name
) && r
.singleton_p (&t
))
138 // valuation_query support routines for value_range_equiv's.
140 class equiv_allocator
: public object_allocator
<value_range_equiv
>
144 : object_allocator
<value_range_equiv
> ("equiv_allocator pool") { }
148 range_query::allocate_value_range_equiv ()
150 return new (equiv_alloc
->allocate ()) value_range_equiv
;
154 range_query::free_value_range_equiv (value_range_equiv
*v
)
156 equiv_alloc
->remove (v
);
159 const class value_range_equiv
*
160 range_query::get_value_range (const_tree expr
, gimple
*stmt
)
163 if (range_of_expr (r
, const_cast<tree
> (expr
), stmt
))
164 return new (equiv_alloc
->allocate ()) value_range_equiv (r
);
165 return new (equiv_alloc
->allocate ()) value_range_equiv (TREE_TYPE (expr
));
168 range_query::range_query ()
170 equiv_alloc
= new equiv_allocator
;
173 range_query::~range_query ()
175 equiv_alloc
->release ();