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. 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) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070712/cafedba4/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: spell-1.0.bc Type: application/octet-stream Size: 28704 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070712/cafedba4/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: time-1.7.bc Type: application/octet-stream Size: 21720 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070712/cafedba4/attachment-0001.obj>
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>
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/