On Mon, Jul 27, 2015 at 12:20 PM, Jakub Jelinek <ja...@redhat.com> wrote: > 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.
Note that TREE_TYPE (t) is the type of the access while the other two types are pointer types. Thus TREE_TYPE (t) might be 'int' for example while the other two are always pointer types. Also TREE_TYPE (t) is used to constrain the minimum alignment of the access - TYPE_ALIGN (t) is supposed to hold at runtime. Richard. > 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). > > Jakub