I've been enhancing prange to track points to information. My current
patch set tracks everything that the side tables in VRP use to, and VRP
is now using that instead
If we see:
char buf1[64];
buf2_9 = &buf1 + 12;
prange will provide a range like: [prange] char * [1, +INF] -> &MEM
<char[64]> [(void *)&buf1 + 12B]
Next, I'd like to see if we can use that to replace all the
pointer_query infrastructure, making it redundant and removable... and
hopefully provide more consistency to it's clients.
Given a generic expression, pointer_query seems to primarily provide a
base reference, offset range and size range for the expression.
So given a generic expression like the above:
&MEM <char[64]> [(void *)&buf1 + 12B]
I'm looking for "base" = &buf1, offset = 12, and size = 64 or
something to that effect. Forget ranges for the moment.. I want to get
the constants extracted from an expression.
Do we have routines that do this generally? I see
tree-dfa.cc::get_ref_base_and_extent () kinda sorta does it, but I'm
also interested in other kinds of expressions, not just a MEM. It looks
like some of this info is buried within pointer_query.cc but I was
wondering if we do it elsewhere more generally.
My longer term goal would be to use ranger to track the offsets and
suchwithin prange as assignments are made and then we can use the info
at appropriate times. ie:
_5 = (sizetype) offset_8(D);
buf2_10 = &buf1 + _5;
For this we now produce buf2_10 = [prange] char * [1, +INF] because
there is no points to expression that can be represented. When asked,
pointer_query chases the def chains and uses ranger to figure out that
offset_8 is [2, 8] and then cobbles that together into into a
pointer_query object that shows the base offset and size..
IF this were integrated properly, then prange should then be able to
produce a range for buf2_10 that looks something like:
[prange] char * [1, +INF] -> &MEM <char[64]> [(void *)&buf1] offset
[2, 8], or maybe even better something like:
[prange] char * [1, +INF] -> &buf1 offset [2, 8] size = [64, 64]
which would naturally be propagated by ranger and when we see it in
another statement:
memcpy (buf2_10, ptr_12(D), 6);
a query for the range of buf2_10 in this statement would provide that
prange, and we'd know the LHS of this is a pointer into a 64 byte
object at an offset between 2 and 8.
First, does this seem like a reasonable extension to replace
pointer_query? It seems like a natural progression of prange. The only
reason pointer_query even exists is because ranger and prange was not
mature enough to be used at the time pointer_query was created. Much of
the code that chases down the definition and ranges in pointer_query
attempts to do what ranger naturally does, but in a very adhoc and
limited way.
Second, do we have any generic processing of expression where I can pick
up the offset and size of the base reference? I will paw through
pointer-query if need be, but it seems like this must be information
that is generally used elsewhere.
Here's a smattering of the kinds of things I currently see in the points
to field:
&MEM <unsigned int[4]> [(void *)&bitint.30 + 4294967292B]
&buf._M_elems
"extern"
&<retval>.coeffs[0]
&MEM <long int[2]> [(void *)&yi + 24B]
&MEM <union tree_node *[2]> [(void *)&mult_oprnd + 8B]
&MEM <struct cmpt[64]> [(void *)&buf + 12B]
&MEM <const char[8]> [(void *)"<stdin>" + 7B]
&p
It may also need more complex expressions later... It probably needs to
work on any generic expression that can represent an object.. but this
is what I see right now so it seems like a good place to start.
Andrew