基于LLVM-分析Pass的制作
分析Pass在实际不修改IR的情况下提供关于IR的更高级的信息,而这些信息可以被其他的分析Pass使用来计算其结果,只要一个分析的Pass计算得出了结果,这个计算结果可以被不同的Pass拿来多次使用,直到一个Pass改变了这个IR
我们先编写下我们需要去进行测试的代码
int func(int a,int b)
{int sum=0;int iter;for (iter = 0; iter< a; iter++) {int iter1;for (iter1=0; itersum+=iter>iter1 ? 1:0;}}return sum;
}
然后我们去利用clang -c -emit-llvm testcode.c -o testcode.bc,去将其转换为.bc文件,也就是字节码文件
之后我们就开始进行编写分析Pass
#define DEBUG_TYPE "opcodeCounter"
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include using namespace llvm;namespace {//此分析Pass是在函数层级上使用的,作用于程序当中的每一个函数,因此,我们在声明CountOpcodes:public FunctionPass结构的时候基础了FunctionPass函数struct CountOpcode:public FunctionPass{std::map<std::string,int>opcodeCounter;static char ID;CountOpcode() : FunctionPass(ID){}virtual bool runOnFunction (Function &F){llvm:outs() << "Function " <'\n';//第一层for循环遍历函数所有的基本块for (Function::iterator bb = F.begin(), e=F.end();bb!=e;++bb ) {//第二层for循环遍历基本块当中的每一条指令for (BasicBlock::iterator i = bb->begin(),e=bb->end(); i!=e;++i) {//判断在map当中有没有过指令,如果没有就直接设置为1//使用find,返回的是被查找元素的位置,没有则返回map.end()if (opcodeCounter.find(i->getOpcodeName())==opcodeCounter.end()) {opcodeCounter[i->getOpcodeName()]=1;}else{//有的就是加一opcodeCounter[i->getOpcodeName()]+=1;}}}std::map<std::string,int>::iterator i = opcodeCounter.begin();std::map<std::string,int>::iterator e = opcodeCounter.end();//遍历输出while(i!=e){llvm::outs()<< i->first << ": "<second << "\n";i++;}llvm::outs()<<"\n";opcodeCounter.clear();//函数没有修改测试代码当中的任何东西,所以返回falsereturn false;}};}//注册Passchar CountOpcode::ID = 0;static RegisterPassX("opcodeCounter","Count number of opcode in a functions");
紧接着我们再通过下面的命令去生成.so动态库
g++ opcodeCount.cpp -fPIC -g -Wall -Wextra -std=c++11 `llvm-config --cppflags ` -shared -o opcodeCount.so
最后通过下面的命令进行链接
opt -load opcodeCount.so -opcodeCounter -disable-output testcode.bc
结果如下所示
Function func
add: 3
alloca: 5
br: 8
icmp: 3
load: 10
ret: 1
select: 1
store: 8
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
