參考:http://www.alonemonkey.com/2016/12/21/learning-llvm/
一芋绸、目的:
寫入opt和clang的命令參數(shù),可以直接參數(shù)指定調(diào)用
二脾猛、使用pass
把上一小節(jié)的pass稍加修改
- 創(chuàng)建頭文件:include/llvm/Transforms/CountOpcode/CountOpcode.h
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"
#define DEBUG_TYPE "opcodecounter"
namespace llvm {
FunctionPass *createCountOpcodePass();
// void initializeCountOpcodePass(PassRegistry &Registry);
}
- cpp文件:lib/Transforms/CountOpcode/CountOpcode.cpp
#include "llvm/Transforms/CountOpcode/CountOpcode.h"
using namespace llvm;
static cl::opt<bool> EnableCountOpcode("opcodeCounter2", cl::init(false),
cl::desc("Count opcode number"));
namespace llvm {
struct CountOpcode : public FunctionPass {
std::map<std::string,int> opcodeCounter;
static char ID;
CountOpcode() : FunctionPass(ID){}
virtual bool runOnFunction(Function &F) {
if(!EnableCountOpcode){
return false;
}
errs()<<"FunctionName:"<<F.getName()<<"\n";
for(Function::iterator bb = F.begin(),e = F.end();bb!=e;++bb){
for(BasicBlock::iterator i = bb->begin(),ie = bb->end();i!=ie;++i){
if(opcodeCounter.find(i->getOpcodeName()) == opcodeCounter.end()){
opcodeCounter[i->getOpcodeName()] =1;
}else{
opcodeCounter[i->getOpcodeName()] +=1;
}
}
}
std::map<std::string,int>::iterator ib = opcodeCounter.begin();
std::map<std::string,int>::iterator ie = opcodeCounter.end();
while (ib != ie) {
errs() << ib->first << " : " << ib->second << "\n";
ib++;
}
errs()<<"\n";
opcodeCounter.clear();
return false;
}
};
FunctionPass * createCountOpcodePass(){
return new CountOpcode();
}
}
char CountOpcode::ID = 0;
//static RegisterPass<CountOpcode> X("opcodeCounter", "Count opcode number", false, false);
INITIALIZE_PASS(CountOpcode, "opcodeCounter", "Count opcode number", false, false)
- 創(chuàng)建LLVMBuild.txt : lib/Transforms/CountOpcode/LLVMBuild.txt
[component_0]
type = Library
name = CountOpcode
parent = Transforms
library_name = CountOpcode
- 創(chuàng)建CMakeLists.txt : lib/Transforms/CountOpcode/CMakeLists.txt
add_llvm_library( LLVMCountOpcode
CountOpcode.cpp
DEPENDS
intrinsics_gen
)
- lib/Transforms/CMakeLists.txt
add_subdirectory(CountOpcode)
- lib/Transforms/LLVMBuild.txt 加上我們的pass
[common]
subdirectories = AggressiveInstCombine Coroutines IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC CountOpcode
- PassManager 注冊(cè)
- lib/Transforms/IPO/PassManagerBuilder.cpp 添加頭文件:
#include "llvm/Transforms/CountOpcode/CountOpcode.h"
- lib/Transforms/IPO/PassManagerBuilder.cpp 函數(shù) populateModulePassManager 添加:
MPM.add(createCountOpcode());
- lib/Transforms/IPO/LLVMBuild.txt 添加:
required_libraries = AggressiveInstCombine Analysis BitReader BitWriter Core InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize Instrumentation CountOpcode
- 相關(guān)頭文件修改:
llvm/LinkAllPasses.h
頭文件添加:
#include "llvm/Transforms/CountOpcode/CountOpcode.h"
(void) llvm::createCountOpcodePass();
llvm/InitializePasses.h
頭文件添加:
void initializeCountOpcodePass(PassRegistry&);
- opt命令參數(shù)添加:
initializeCountOpcodePass(Registry);
最后分別編譯opt和clang勺爱。
- 編譯可能的問題:
- 最終鏈接找不到新pass的符號(hào)笙以,需要在鏈接flag配置新創(chuàng)建pass庫(kù)的路徑:
ld: symbol(s) not found for architecture x86_64
如下配置鏈接庫(kù):
image.png
四饱苟、opt 和 clang執(zhí)行:
-
opt 參數(shù)與運(yùn)行結(jié)果:
image.png
image.png
-
clang 參數(shù)與運(yùn)行結(jié)果:
image.png