On Mon, Jul 27, 2015 at 4:43 PM, Uday P. Khedker <u...@cse.iitb.ac.in> wrote: > > > 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 *"?
As Jakub said this is not the full story if you factor in type-based aliasing. Also you of course have to account for the offset in operand 1. Richard. > Uday. >