2016-02-15 35 views
0

我很新写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; 
    } 
    }; 
} 
+0

你看过[LLVM程序员手册](http://llvm.org/docs/ProgrammersManual.html)吗? –

回答

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

+0

我得到和错误说:错误:'llvm :: CallInst :: CallInst(const llvm :: CallInst&)'是私人 – Kroka