[LLVMdev] Add call printf instructions problems

Jin Huang 54jin.huang at gmail.com
Mon Dec 16 05:49:50 PST 2013


Hello, everyone!
  I want to write a pass which can insert a call "printf" instructions
before every instruction in the LLVM IR. here is what I wrote:

namespace {
class call_print : public FunctionPass{

private:
DenseMap<const Value*, int> inst_map;

public:
static char ID;
call_print() : FunctionPass(ID){}
 //define a extern function "printf"
static llvm::Function*
printf_prototype(llvm::LLVMContext& ctx, llvm::Module *mod)
{
    std::vector<llvm::Type*> printf_arg_types;
    printf_arg_types.push_back(llvm::Type::getInt32Ty(ctx));

    llvm::FunctionType* printf_type =
        llvm::FunctionType::get(llvm::Type::getInt32Ty(ctx),
printf_arg_types, true);

    llvm::Function *func = llvm::Function::Create(printf_type,
llvm::Function::ExternalLinkage,
                llvm::Twine("printf"),mod);
    func->setCallingConv(llvm::CallingConv::C);
    return func;
}
 //get a printf function
Function* Get_print()
{
llvm::LLVMContext& ctx = llvm::getGlobalContext();
Module* mod = new Module("test",ctx);
// Constant* c = mod->getOrInsertFunction("printf");
Function *printf_func = printf_prototype(ctx, mod);
printf_func->setCallingConv(CallingConv::C);
return printf_func;
}

virtual bool runOnFunction(Function &F)
{
int id = 0;
// get a Function
Function *call_print = Get_print();
for(inst_iterator i = inst_begin(F),e = inst_end(F);i != e; i++,id++)
{
errs()<<"@"<<id<<": "<<*i<<"\n";
std::vector<llvm::Value*> paramArrayRef;
Value *a = ConstantInt::get(Type::getInt32Ty(getGlobalContext()),1);
paramArrayRef.push_back(a);
// get an instruction pointer
Instruction* ins_temp = &*i;
//create a call instruction and insert it before every instruction
CallInst *call_print =
CallInst::Create(call_print,paramArrayRef,"",ins_temp);
 DEBUG(errs()<<"insert an instruction:"<<*call_print<<"\n");

}

return true;
}
};
 char call_print::ID = 1;
// register the printCode class:
  //  - give it a command-line argument (printCode)
  //  - a name ("print code")
  //  - a flag saying that we don't modify the CFG
  //  - a flag saying this is not an analysis pass
  RegisterPass<call_print> X("call_print", "call print func",
   false, false);

}

I successfully compile it .but when I use the call_print.so to transform
the test .bc file like this:

opt -load /home/king/llvm/Release+Asserts/lib/call_print.so -call_print
<test_sum.bc> test_sum.call.bc -debug

It failed with such information:

 /home/king/llvm/include/llvm/Support/Casting.h:237: typename
enable_if<is_same<Y, typename simplify_type<Y>::SimpleType>, typename
cast_retty<X, Y *>::ret_type>::type llvm::cast(Y *) [X = llvm::PointerType,
Y = llvm::Type]: Assertion `isa<X>(Val) && "cast<Ty>() argument of
incompatible type!"' failed.

Can anyone tell me what the problem is ? And whether I wrote the pass right
?
Thank you!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131216/0b1c364b/attachment.html>


More information about the llvm-dev mailing list