通过查找方法调用次数

时间:2016-02-15 15:45:41

标签: compiler-construction llvm

我是编写LLVM通道的新手,如果我想计算主函数调用printf()的次数(作为示例),我想知道我应该添加到通道中的内容。

说我有这个非常令人兴奋的主要内容:

#include <stdio.h>

int main() {
  printf("hello world\n");
  return 0;
}

我希望我的传递看看printf()是否被调用以及调用它的次数(例如,如果它在某些循环中)。

到目前为止,这是我通过的内容:

namespace {
  struct SkeletonPass : public FunctionPass {
    static char ID;
    SkeletonPass() : FunctionPass(ID) {}

    virtual bool runOnFunction(Function &F) {
      errs() << "I saw a function called " << F.getName() << "!\n";
      errs() << "It uses printf()" << F. //I'd like to write out how many     times printf() is used here
      return false;
    }
  };
}

1 个答案:

答案 0 :(得分:1)

如果您只想检查printf是否被调用,而不是通过CFG。

llvm子类runOnFunction为每个函数体运行,你可以遍历函数指令并检查它们是否是CallInst并调用特别是printf。

inst_iterator inst = inst_begin(&F);
inst_iterator instEnd = inst_end(&F);
for(; inst != instEnd; ++inst)
{
    if (CallInst* psCall = dyn_cast<CallInst>(&*inst))
    {
        StringRef name = psCall->getCalledFunction()->getName();
        /* check name */
    }
}

现在检查它是否在循环中。有一个子类runOnLoop但是LPPassManager接口应该用于更新循环嵌套。(如果你想更新它)

用于控制流搜索,

BasicBlocks已经以CFG方式组织,它们有后继者和前身,所以你不必建立新的图形。 您可以使用简单的递归DFS算法来完成cfg。

看这里 http://eli.thegreenplace.net/2013/09/16/analyzing-function-cfgs-with-llvm 这家伙解释得好多了。

还可以查看llvm手册,找到更好的接口和程序。 http://llvm.org/docs/WritingAnLLVMPass.html