I am doing inter-procedural static analysis, so I need to do DFS of call graph. llvm-gcc sometimes generates this kind of call instruction, which cause the call graph to be incomplete. But thanks for your information, instcombine really solves the problem. On 7/17/07, Chris Lattner <sabre at nondot.org> wrote:> > On Thu, 12 Jul 2007, Zhongxing Xu wrote: > > The current BasicCallGraph will miss call sites like this: > > %tmp86 = call i8* (...)* bitcast (i8* ()* @find_ispell to i8* (...)*)( ) > > ; <i8*> [#uses=1] > > > > Here the direct user of @find_ispell is a ConstantExpr. > > I added several lines of code to address this case. > > Below is the output of command: svn diff lib/Analysis/IPA/CallGraph.cpp > > Attached is LLVM asm files with such function calls. > > This is problematic, because it's not checking for the type of constant > expr (i.e. is it a bitcast, etc). That can easily be fixed, but here's a > basic question: when is this important? The instcombine pass should fix > up these bitcasts, so they shouldn't occur frequently in practice. When > have you found this to be important? > > Thanks, > > -Chris > > > Index: lib/Analysis/IPA/CallGraph.cpp > > ==================================================================> > --- lib/Analysis/IPA/CallGraph.cpp (revision 39771) > > +++ lib/Analysis/IPA/CallGraph.cpp (working copy) > > @@ -13,6 +13,7 @@ > > > //===----------------------------------------------------------------------===// > > > > > > #include "llvm/Analysis/CallGraph.h" > > +#include "llvm/Constants.h" > > # include "llvm/Module.h" > > # include "llvm/Instructions.h" > > # include "llvm/Support/CallSite.h" > > @@ -150,6 +151,19 @@ > > -> addCalledFunction(CS, Node); > > else > > isUsedExternally = true; > > + } else if (ConstantExpr* CE = dyn_cast<ConstantExpr>(*I)) { > > + for (Value::use_iterator I = CE->use_begin(), E > CE->use_end(); > > + I != E; ++I) > > + if (Instruction* Inst = dyn_cast<Instruction>(*I)) { > > + CallSite CS = CallSite::get(Inst); > > + if (isOnlyADirectCall(F, CS)) > > + getOrInsertFunction(Inst->getParent()->getParent()) > > + ->addCalledFunction(CS, Node); > > + else > > + isUsedExternally = true; > > + } else { > > + isUsedExternally = true; > > + } > > } else if (GlobalValue *GV = dyn_cast<GlobalValue>(*I)) { > > for (Value::use_iterator I = GV->use_begin(), E > GV->use_end(); > > I != E; ++I) > > > > > > -Chris > > -- > http://nondot.org/sabre/ > http://llvm.org/ > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070717/95fb69f9/attachment.html>
> Happy to help. You'll probably find that other optimizations help as > well, such as simplifycfg (which deletes dead blocks).Thank you. I am using it. Depending on what> you are doing, using the LLVM IR can be tricky for this sort of stuff > because it can get too far from the source level. >Yes, it is really a problem. Now I am using my eyes to map the LLVM IR back to the source code. But it's tedious and error prone. Is there any better way to do this? I guess carrying debug information in LLVM IR might help. But I don't know how to use the debug information. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070717/618f2548/attachment.html>
On Tue, 17 Jul 2007, Zhongxing Xu wrote:> I am doing inter-procedural static analysis, so I need to do DFS of call > graph. llvm-gcc sometimes generates this kind of call instruction, which > cause the call graph to be incomplete. > > But thanks for your information, instcombine really solves the problem.Happy to help. You'll probably find that other optimizations help as well, such as simplifycfg (which deletes dead blocks). Depending on what you are doing, using the LLVM IR can be tricky for this sort of stuff because it can get too far from the source level. -Chris> On 7/17/07, Chris Lattner <sabre at nondot.org> wrote: >> >> On Thu, 12 Jul 2007, Zhongxing Xu wrote: >> > The current BasicCallGraph will miss call sites like this: >> > %tmp86 = call i8* (...)* bitcast (i8* ()* @find_ispell to i8* (...)*)( ) >> > ; <i8*> [#uses=1] >> > >> > Here the direct user of @find_ispell is a ConstantExpr. >> > I added several lines of code to address this case. >> > Below is the output of command: svn diff lib/Analysis/IPA/CallGraph.cpp >> > Attached is LLVM asm files with such function calls. >> >> This is problematic, because it's not checking for the type of constant >> expr (i.e. is it a bitcast, etc). That can easily be fixed, but here's a >> basic question: when is this important? The instcombine pass should fix >> up these bitcasts, so they shouldn't occur frequently in practice. When >> have you found this to be important? >> >> Thanks, >> >> -Chris >> >> > Index: lib/Analysis/IPA/CallGraph.cpp >> > ==================================================================>> > --- lib/Analysis/IPA/CallGraph.cpp (revision 39771) >> > +++ lib/Analysis/IPA/CallGraph.cpp (working copy) >> > @@ -13,6 +13,7 @@ >> >> > //===----------------------------------------------------------------------===// >> > >> > >> > #include "llvm/Analysis/CallGraph.h" >> > +#include "llvm/Constants.h" >> > # include "llvm/Module.h" >> > # include "llvm/Instructions.h" >> > # include "llvm/Support/CallSite.h" >> > @@ -150,6 +151,19 @@ >> > -> addCalledFunction(CS, Node); >> > else >> > isUsedExternally = true; >> > + } else if (ConstantExpr* CE = dyn_cast<ConstantExpr>(*I)) { >> > + for (Value::use_iterator I = CE->use_begin(), E >> CE->use_end(); >> > + I != E; ++I) >> > + if (Instruction* Inst = dyn_cast<Instruction>(*I)) { >> > + CallSite CS = CallSite::get(Inst); >> > + if (isOnlyADirectCall(F, CS)) >> > + getOrInsertFunction(Inst->getParent()->getParent()) >> > + ->addCalledFunction(CS, Node); >> > + else >> > + isUsedExternally = true; >> > + } else { >> > + isUsedExternally = true; >> > + } >> > } else if (GlobalValue *GV = dyn_cast<GlobalValue>(*I)) { >> > for (Value::use_iterator I = GV->use_begin(), E >> GV->use_end(); >> > I != E; ++I) >> > >> > >> >> -Chris >> >> -- >> http: //nondot.org/sabre/ >> http: //llvm.org/ >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >-Chris -- http://nondot.org/sabre/ http://llvm.org/