Hi All,
I am trying to write code for simple instrumentation. What I want to do is to insert a call to an external function for result of each conditional branch instruction. This external function simply print true or false based on the result of condition. The modified code is then written into new file. However when I try to link that file with another bitcode file (containing external function), it results “llvm-link: error loading file ‘newfile.bc’” error. This error is inconsistent. It appears for some programs and not for some other. If it links with other file, during execution it produces following error - Assertion `Addr && “Code generation didn’t add function to GlobalAddress table!”’ failed
Below is the code of my pass. It inherits ModulePass and does not have any other method except runOnModule. Am I missing something during call insertion or bitcode modification? I am using LLVM-2.6. The same code in LLVM-2.5 works correctly. (except Type::getInt32Ty, llvm-2.5 has Type::Int32Ty and no LLVMContext object)
Thanks,
Nehal
bool ConditionProfile::runOnModule(Module &M)
{
// Iterates through all functions of the module
for(Module::iterator mi = M.begin(), me = M.end(); mi!=me; mi++)
{
// Iterates through all basic blocks of the function
for(Function::iterator fi = mi->begin(), fe = mi->end(); fi!=fe; fi++)
{
BasicBlock::iterator bi = fi->end();
bi–; // Getting the terminator/last instruction of BasicBlock
if(isa(bi))
{
BranchInst *brInst = cast(bi);
// We are interested in conditional branch only
if(brInst->isUnconditional()) continue;
Value *condRes = brInst->getCondition();
errs()<<“Type:”<getType()->getDescription()<<"\n";
// Looking for a function in Module Symbol table
Constant *PrintFn = M.getOrInsertFunction("_Z12PrintCondResb", Type::getInt32Ty(context), condRes->getType(), (Type *)0);
if(!PrintFn) {
errs()<<“GetOrInsertFailed\n”;
continue;
}
std::vector<Value *> args(1);
args[0] = condRes;
// Creating a call instruction to above function.
CallInst *callInst =
CallInst::Create(PrintFn, args.begin(), args.end(), “”, bi);
callInst->setCallingConv(CallingConv::Fast);
}
}
}
// Writing modified module to new file.
std::ostream *os = new std::ofstream(“newfile.bc”);
WriteBitcodeToFile(&M, *os);
return true;
}