Hi Reid, Thank you for your response. In my analysis, I will always have entry(2) and exit(2). I will not run into cases involving entry (1+1) or entry (fn return values). I am having trouble trying to compare the arguments of entry and exit in the following scenario. #include<stdio.h> #include<stdlib.h> #include<pthread.h> struct sa { int a; pthread_mutex_t *mutex1; }; struct sa *s; pthread_mutex_t mutex1; int main() { s = (struct sa *)malloc(sizeof(struct sa)); s->mutex1 = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); entry(s->mutex1); s->a++; exit(s->mutex1); return 0; } Thanks in advance, Best, --Hari On 03/07/2011 01:04 PM, Reid Kleckner wrote:> Could you be more precise about what you mean by "identical"? Would > entry(2) and entry(1+1) be considered equivalent? > > If the same Value* is passed to entry and exit, then pointer equality > (==) will detect that. > > Reid > > On Mon, Mar 7, 2011 at 8:08 AM, Hari Pyla<harip at vt.edu> wrote: >> Hi, >> I am trying to identify if two functions were called with exactly the same argument. For instance, in the below example, assuming both entry() and exit() functions take a single argument, I would like to know if arg1 in entry() is same as arg1in exit(). >> >> int a; >> struct sa >> { >> int b; >> int c; >> }; >> >> int main () >> { >> struct sa s; >> >> entry (arg1); >> ... >> exit (arg1); >> >> return 0; >> } >> >> In instances such as entry(a) and exit (a). I am able to determine that it is the same variable 'a' using '==' on the callinst->getOperand(1)'. However, if I pass a member variable of a structure say (s.b) to both entry and exit, I am unable to use '==' since the operands are GEP instructions. How can I compare such arguments to check if they are identical and also I was wondering as to what is best approach to determine if these arguments are exactly identical. Thanks in advance. >> >> Best, >> --Hari >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>
On Mon, Mar 7, 2011 at 8:03 PM, Hari Pyla <harip at vt.edu> wrote:> Thank you for your response. In my analysis, I will always have > entry(2) and exit(2). I will not run into cases involving entry (1+1) or > entry (fn return values). I am having trouble trying to compare the > arguments of entry and exit in the following scenario. > > #include<stdio.h> > #include<stdlib.h> > #include<pthread.h> > > struct sa > { > int a; > pthread_mutex_t *mutex1; > }; > struct sa *s; > > pthread_mutex_t mutex1; > int main() > { > s = (struct sa *)malloc(sizeof(struct sa)); > s->mutex1 = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); > > entry(s->mutex1); > > s->a++; > > exit(s->mutex1); > > return 0; > }Have you tried just running something like -earlycse before your pass? It might be overkill, but it'd probably get the job done. If you want a "lazy" check (as in, just for the values you want to compare) though, AFAIK there's no public interface for that kind of functionality. A pass like -earlycse or -mergefunc might have something you can factor out though. Other than that, you can probably hack up something with a recursive function using Instruction::isSameOperationAs(), which checks everything except operand values (so you'd need to check equivalence of operands recursively if you want to go more than one instruction deep). You'll probably want to keep a mapping of already-checked equivalences (for performance), and you should definitely be careful not to go into infinite recursion in the face of PHI nodes. Also, be careful of side effects, both in the instructions you're comparing and in anything in between; for example you don't want two loads to be considered equal if there's a store to that memory in between them. Instruction::mayHaveSideEffects() and Instruction::mayReadFromMemory() are probably useful here. If you go with either of the last two options and create a function to figure out whether two values are equivalent, it might be interesting if you submitted a patch for your changes so others can use them too. Also, you'd likely get some feedback on whether you've made any mistakes :).
Hi, I downloaded the latest llvm (dev version) and I tried -earlycse with opt before my pass. However, it still does not solve my problem. I will try to explore the recursive function option and I will certainly send you the code once I implement it. Thanks, --Hari On 03/07/2011 03:02 PM, Frits van Bommel wrote:> On Mon, Mar 7, 2011 at 8:03 PM, Hari Pyla<harip at vt.edu> wrote: >> Thank you for your response. In my analysis, I will always have >> entry(2) and exit(2). I will not run into cases involving entry (1+1) or >> entry (fn return values). I am having trouble trying to compare the >> arguments of entry and exit in the following scenario. >> >> #include<stdio.h> >> #include<stdlib.h> >> #include<pthread.h> >> >> struct sa >> { >> int a; >> pthread_mutex_t *mutex1; >> }; >> struct sa *s; >> >> pthread_mutex_t mutex1; >> int main() >> { >> s = (struct sa *)malloc(sizeof(struct sa)); >> s->mutex1 = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); >> >> entry(s->mutex1); >> >> s->a++; >> >> exit(s->mutex1); >> >> return 0; >> } > Have you tried just running something like -earlycse before your pass? > It might be overkill, but it'd probably get the job done. > > If you want a "lazy" check (as in, just for the values you want to > compare) though, AFAIK there's no public interface for that kind of > functionality. A pass like -earlycse or -mergefunc might have > something you can factor out though. > > Other than that, you can probably hack up something with a recursive > function using Instruction::isSameOperationAs(), which checks > everything except operand values (so you'd need to check equivalence > of operands recursively if you want to go more than one instruction > deep). > You'll probably want to keep a mapping of already-checked equivalences > (for performance), and you should definitely be careful not to go into > infinite recursion in the face of PHI nodes. > Also, be careful of side effects, both in the instructions you're > comparing and in anything in between; for example you don't want two > loads to be considered equal if there's a store to that memory in > between them. Instruction::mayHaveSideEffects() and > Instruction::mayReadFromMemory() are probably useful here. > > If you go with either of the last two options and create a function to > figure out whether two values are equivalent, it might be interesting > if you submitted a patch for your changes so others can use them too. > Also, you'd likely get some feedback on whether you've made any > mistakes :).