On Tue, Dec 8, 2015 at 3:22 PM, Uday P. Khedker <u...@cse.iitb.ac.in> wrote:
>
>
> Richard Biener wrote on 12/03/2015 03:32 PM:
>>
>> On Thu, Dec 3, 2015 at 8:54 AM, Uday P. Khedker <u...@cse.iitb.ac.in>
>> wrote:
>>>
>>> We are implementing points-to analysis in GCC 4.7.2 and need to
>>> distinguish
>>> between
>>> pointers to scalars and the pointers to structures. This distinction by
>>> using the TYPE (TREE_TYPE)
>>> hierarchy of the tree node of the pointer. We have two questions:
>>>
>>> (a) Is it sufficient to check for the presence of RECORD_TYPE in type
>>> hierarchy?
>>> (b) Is it safe to assume that the RECORD_TYPE always appears as a leaf
>>> node
>>> in
>>>      the type description of any pointer to structure?
>>>
>>> As an example, the tree nodes of a pointer to an integer (y) and a
>>> pointer
>>> to a structure (f)
>>> below. It seems to support our hunch.
>>
>> Yes, your observations are correct with respect to types.
>>
>> But you can't rely on the pointer type for determining what kind of
>> object apointer points to.
>> First because of int *p = &s.i;  with struct { int i; ... } s; points
>> to an int but it also points
>> to the start of an aggregate (and so can be trivially casted to a
>> pointer to s).  Second because
>> GCCs middle-end (thus GIMPLE) ignores pointer types completely so you can
>> have
>> an SSA name a_1 of type int *X and a dereference a_1->b.c (thus a_1 points
>> to a
>> structure object even though it is of type int *).
>>
>
> Thanks for this word of caution :)
>
> We understand your example (where SSA variable a_1 is of type int * and it
> is dereferenced as a_1->b.c) with the following explanation: Since GIMPLE
> based transformations ignore the type information completely, it could
> differ flow sensitively for variables and is left implicit. In other words,
> the type of a variable in an expression could differ from its type available
> in VAR_DECL. For the above example, the type of a_1 in VAR_DECL is int *
> whereas it is actually used as a pointer to a struct in the expression
> a_1->b.c because of some code transformations.
>
> Fortunately, we do not need the flow sensitive type of a variable in every
> expression.
>
> Our basic need is much simpler: We would like to know if a pointer is used
> for iteratively accessing a recursive data structure (such as a list),  in a
> loop or recursive invocation as illustrated below. Due to some
> transformations, can a pointer to int show up for such accesses in GIMPLE or
> would it always have RECORD_TYPE in its type expression for such limited
> situations?
>
> while (...)
> {
>     x = x->f;
>     ...
> }
>
> At the source level, x is guaranteed to be a pointer to a struct. Our
> question is: Does this guarantee hold in GIMPLE in the limited situations of
> such iterative accesses to a recursive data structure?

No, it doesn't.

> In particular, if this guarantee does not hold for a sequential access
> pattern such as below, it is a non-issue for us.
>
> x = x->f;
> x = x->f;
> x = x->f;

struct X { struct X *f; };
struct X *foo (void *p)
{
  p = ((struct X *)p)->f;
  p = ((struct X *)p)->f;
  p = ((struct X *)p)->f;
  return p;
}

is represented as

foo (void * p)
{
  <bb 2>:
  p_3 = MEM[(struct X *)p_2(D)].f;
  p_4 = MEM[(struct X *)p_3].f;
  p_5 = MEM[(struct X *)p_4].f;
  return p_5;
}

all pointer types are void *.  At accesses you have types of access of course,
but the pointers themselves can have any pointer type (such as void * here
or int * if you change the type of p).

Richard.

> What gives us a ray of hope is our hunch that the code transformations for
> iterative accesses are far more limited than they are for sequential
> accesses.
>
> Thanks and regards,
>
> Uday.
>
>
>

Reply via email to