我想插入一个计数器来记录基本块执行的次数。
我采取的步骤:
我编写了名为BlockProfiling.cpp
我用以下代码编译:
$ g++ -c BlockProfiling.cpp _i/usr/local/include `llvm-config --cxxflag`
它生成一个名为BlockPrpfiling.o
我跑:
$ g++ -shared -o BlockProfiling.so BlockProfiling.o -L/usr/local/lib `llvm-config --ldflags -libs`
它会生成一个名为BlockProfiling.so
我用它来检测我的文件test.bc
并生成test.bb.bc
:
$opt -load=./BlockProfiling.so -insert-bb-profling test.bc -o test.bb.bc
我使用llvm-diff确认已完成。
但是当我使用lli执行test.bb.bc时,会出现一个错误:
LLVM错误:程序使用了无法解析的外部函数'llvm_start_func_profiling'!
任何解决方案?
llvm版本是3.3,这是我的代码:
namespace{
struct BlockProfiler: public ModulePass{
static char ID;
BlockProfiler():ModulePass(ID) {
initializeBlock ProfilerPass(*Registry::getPassRegistry());
}
virtual bool runOnModule(Module &M);
}; //end of function profiling pass
} //end of namespace
char BlockProfiler::ID = 0 ;
INITIALIZE_PASS(BlockProfiler, "insert-block-profiling",
"Insert instrumentation for profiling", false, false )
ModulePass *llvm::createBlockProfilerPass() {return new BlockProfiler() ; }
//static RegisterPass<BlockProfilerPass> Y("insert-block-profiling",
"Insert instrumentation for block profiling");
bool BlockProfiler::runOnModule(Module &M){
Function *Main = M.getFunction("main") ;
if(Main == 0)
{
errs()<<" WARING: cannot insert block profiling into a module"
<<" with no main function. \n" ;
return false ; // no main, no instrumentation, and no modify
}
unsigned NumBlocks = 0;
for(Module::iterator I = M.begin(), E = M.end(); I != E ; ++I)
NumBlocks += I->size();
Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), NumBlocks) ;
GlobalVariable *Counters =
new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATy), "BlockProCounters") ;
//Instrument all of the blocks
unsigned i = 0;
for(Module::iterator I = M.begin(), E = M.end(); I != E; ++I){
for(Function::iterator BB = I->begin(), E = I->end() ; BB != E; ++BB )
//Insert counter at the start of the block
IncrementCounterInBlock(BB, i++, Counters);
}
//add the initialization call to main
InsertProfilingInitCall(Main, "llvm_start_block_profiling", Counters);
return true;
}