On 10/6/20 3:27 PM, Martin Sebor wrote:
On 10/5/20 8:18 PM, Andrew MacLeod wrote:
On 10/5/20 4:16 PM, Martin Sebor wrote:
Long term, I would expect we might have some sort of general
access... probably thru cfun. so any pass/routines would just ask
for
RANGE_INFO (cfun)->range_of_expr()
The default would be a general value_range implementation which
probably implements something like determine_value_range_1 ().. and
if a pass wants to use a ranger, then it could register a ranger, and
when its done delete it. and it would just work for everyone
everywhere.
That would work too.
As a side note, I don't yet fully understand when it might be useful
to have different range_query instances. We talked about value_query
and range_query but those are provided because some passes work with
just values and others with just ranges. When might one want to have
an instance of some other type altogether and tie it to a function?
I don't know what you are asking. An instance of some other type
altogether?
we have 2 instances of range_query already. m_range_analyzer and
ranger.
we have multiple instances of value_query as well, in that they are used
by CCP and the other converted passes and they provide their own version
of value_of_expr to get what they want.
the hybrid ranger utilizes 2 concurrent instances of different
range_query's to function right now, and uses the combined results.
GCC currently has no concept of a "global" range analyzer. Its all been
pass specific with EVRP and VRP being the 2 engines, and they both set
some minimal global ranges that can be picked up elsewhere. EVRP was
enhanced to allow other passes to hook into it via a DOM walk (Like DOM
and threading), but it was still pass specific information. We've added
Ranger with the longer term goal to replace both of the other engines.
The other passes have all been converted to this model fairly painlessly
as most passes have some sort of local pass information awareness, so
creating and accessing a range query engine wasnt a big deal.
I dont know if or when we will "promote" a ranger to a global access
thing.. there hasn't been a need, but if there is more and more good
reason, then its something we will certainly look at. Maintaining
global ranges across passes is not something that is easy to do, and not
something we are likely to, so we'll need to respawn a new ranger for
any pass that needs it anyway. So having a pass spawn its own doesnt
seem like a big stretch for now.
but we're not there yet, and we havent worked out the details :-) for
the moment, passes need to figure out themselves how to access the
ranger they create if they want one. They had to manage a
range_analyzer before if they used anything other than global ranges,
so that is nothing new.
For EVRP, yes. For everything else there's the global get_range_info.
It got ugly when a utility function like get_size_range was changed
to work with both. I made that change and didn't like it then. I'm
trying to brainstorm ways to avoid spreading that wart too much
further.
Its not just evrp, and I assure you, thats not the ugliest thing in GCC :-).
we cant do everything up front, or it would be another 2 years before
things happen. until then, we work around things and fix them up when
we can get to them.
Seems to me that either get_size_range takes a range_query object to get
a range, or there are 2 versions.., or it is in the wrong place now
because its a global function trying to access contextual information,
and becomes part of a class which has/is/uses a range_query object.
Looking at it, it doesnt seem to be anything more than range_of_expr,
plus some odd ANTI_RANGE stuff which can be completely avoided with a
ranger and multirange support.
in fact, I think
if (range_of_expr (r, exp, stmt)
pretty much does it? handles all the integral values, constants.
symbolic lookups and returns FALSE if it isnt integral. You wont see an
anti range if you use int_range<2> or higher, but you might see multiple
ranges if it was an anti range before.. although you may only care about
the lower_bound() and upper_bound()... I dont know.
Of course you still need to access a ranger to make that call :-)
rangers are pretty lightweight for occasional queries... maybe the place
to start is simply spawning a new one for each request and see where
that gets you. In fact, I think thats what Aldy use to do in
determine_value_range on the branch :-P I think the bottom line is
if a pass is going to move from purely global information to something
that is contextual, it has new constraints it didnt have before and may
need some additional reshuffling to look pretty.
Andrew