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/