Jakub Jelinek wrote on Monday 27 July 2015 03:50 PM:
On Mon, Jul 27, 2015 at 03:35:45PM +0530, Uday Khedker wrote:
We are interested in extracting the type of a tree node that appears within
MEM_REF.

Given a C program:

     struct node * * pvar;
     struct node qvar;
     pvar = (struct node * *) malloc (sizeof (struct node *));
     *pvar = &qvar;

It is transformed into the following GIMPLE code:

     void * * pvar.1;
     void * pvar.0;
     pvar.0_1 = malloc (4);
     pvar = pvar.0_1;
     MEM[(struct node * *)pvar.0_1] = &qvar;

We wish to discover the type of the argument of MEM[...] in the last
GIMPLE statement. We can see from the GIMPLE dump that the argument's
type is "struct node * *". How do we extract this from the tree
definition of MEM[...]?

We speculate the following solution: Given a variable var (whose tree is
tree_of_var) and a tree, say t,

     if (TREE_CODE(t) is MEM_REF) and (TREE_OPERAND(t, 0) is tree_of_var)
     then
         the type of the expression inside MEM[...] of tree t is
         POINTER_TYPE to TREE_TYPE(t).

Is is correct? It is general enough?
A MEM_REF has 3 possibly distinct types.  If TREE_CODE (t) == MEM_REF,
one type, TREE_TYPE (t), is the type of the access, struct node *
in the above case.  Another type is one for alias analysis purposes,
stored in TREE_TYPE (TREE_OPERAND (t, 1)), this one will be
struct node ** in your case.  And yet another type is the type of the
pointer, TREE_TYPE (TREE_OPERAND (t, 0)), which usually is the same
as pointer to TREE_TYPE (t) initially, but as most of pointer conversions
are regarded as useless, after optimization passes you often can end up
there with very different type.

In our case, TREE_TYPE (TREE_OPERAND (t, 0)) as extracted from the tree node turns out to 
be "void *" which is same as the original type of the variable pvar.0.

From your reply, can I conclude that because of the type cast operation, I can 
ignore the TREE_TYPE (TREE_OPERAND (t, 0)) recorded in the tree and instead 
take it to be pointer to TREE_TYPE(t)?

The type for alias analysis purposes can also differ from pointer to
TREE_TYPE (t), consider e.g.
   short *p = ...;
   int i = 26;
   memcpy (p, &i, sizeof (int));
which is folded (depending on alignment behavior) as MEM_REF[(int *)p] = 26;
and here TREE_TYPE (t) will be int, TREE_TYPE (TREE_OPERAND (t, 0)) likely
short * and TREE_TYPE (TREE_OPERAND (t, 1)) likely char * (ref_all).
Here the TREE_TYPE (TREE_OPERAND (t, 0)) suggested by you is consistent with our 
observation (here it is "short *" which is same as the original type).

The question is: can we safely conclude that for the purpose of this operation (i.e. in 
this GIMPLE statement), p is being viewed as pointer to TREE_TYPE(t) which is "int 
*"?

Uday.

Reply via email to