[LLVMdev] BasicCallGraph patch

Chris Lattner sabre at nondot.org
Mon Jul 16 23:17:10 PDT 2007


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/



More information about the llvm-dev mailing list