<div dir="ltr">Hello, everyone!<div>  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:</div><div><br></div><div><div>namespace {</div>
<div><span class="" style="white-space:pre">    </span>class call_print : public FunctionPass{</div><div><br></div><div><span class="" style="white-space:pre">   </span>private:</div><div><span class="" style="white-space:pre">           </span>DenseMap<const Value*, int> inst_map;</div>
<div><br></div><div><span class="" style="white-space:pre">   </span>public:</div><div><span class="" style="white-space:pre">            </span>static char ID;</div><div><span class="" style="white-space:pre">            </span>call_print() : FunctionPass(ID){}</div>
<div><span class="" style="white-space:pre">            </span></div><div><span class="" style="white-space:pre">           </span>//define a extern function "printf"</div><div><span class="" style="white-space:pre">              </span>static llvm::Function*<span class="" style="white-space:pre">    </span></div>
<div><span class="" style="white-space:pre">            </span>printf_prototype(llvm::LLVMContext& ctx, llvm::Module *mod)</div><div><span class="" style="white-space:pre">            </span>{</div><div>    <span class="" style="white-space:pre">                      </span>std::vector<llvm::Type*> printf_arg_types;</div>
<div>    <span class="" style="white-space:pre">                        </span>printf_arg_types.push_back(llvm::Type::getInt32Ty(ctx));</div><div><br></div><div>    <span class="" style="white-space:pre">                      </span>llvm::FunctionType* printf_type =</div>
<div>        <span class="" style="white-space:pre">                    </span>llvm::FunctionType::get(llvm::Type::getInt32Ty(ctx), printf_arg_types, true);</div><div><br></div><div>    <span class="" style="white-space:pre">                 </span>llvm::Function *func = llvm::Function::Create(printf_type, llvm::Function::ExternalLinkage,</div>
<div>                llvm::Twine("printf"),mod);</div><div>    <span class="" style="white-space:pre">                    </span>func->setCallingConv(llvm::CallingConv::C);</div><div>   <span class="" style="white-space:pre">                  </span> return func;</div>
<div><span class="" style="white-space:pre">            </span>}</div><div><span class="" style="white-space:pre">          </span></div><div><span class="" style="white-space:pre">           </span>//get a printf function</div><div><span class="" style="white-space:pre">            </span>Function* Get_print()</div>
<div><span class="" style="white-space:pre">            </span>{</div><div><span class="" style="white-space:pre">                  </span>llvm::LLVMContext& ctx = llvm::getGlobalContext();</div><div><span class="" style="white-space:pre">                     </span>Module* mod = new Module("test",ctx);</div>
<div><span class="" style="white-space:pre">            </span>//<span class="" style="white-space:pre">        </span>Constant* c = mod->getOrInsertFunction("printf");</div><div><span class="" style="white-space:pre">                     </span>Function *printf_func = printf_prototype(ctx, mod);<span class="" style="white-space:pre">       </span></div>
<div><span class="" style="white-space:pre">                    </span>printf_func->setCallingConv(CallingConv::C);</div><div><span class="" style="white-space:pre">                    </span>return printf_func;</div><div><span class="" style="white-space:pre">                </span>}</div>
<div><br></div><div><span class="" style="white-space:pre">           </span>virtual bool runOnFunction(Function &F)</div><div><span class="" style="white-space:pre">                </span>{</div><div><span class="" style="white-space:pre">                  </span>int id = 0;</div>
<div><span class="" style="white-space:pre">                    </span>// get a Function</div><div><span class="" style="white-space:pre">                  </span>Function *call_print = Get_print();</div><div><span class="" style="white-space:pre">                        </span>for(inst_iterator i = inst_begin(F),e = inst_end(F);i != e; i++,id++)</div>
<div><span class="" style="white-space:pre">                    </span>{</div><div><span class="" style="white-space:pre">                          </span>errs()<<"@"<<id<<": "<<*i<<"\n";</div><div><span class="" style="white-space:pre">                               </span>std::vector<llvm::Value*> paramArrayRef;</div>
<div><span class="" style="white-space:pre">                            </span>Value *a = ConstantInt::get(Type::getInt32Ty(getGlobalContext()),1);</div><div><span class="" style="white-space:pre">                               </span>paramArrayRef.push_back(a);</div><div>
<span class="" style="white-space:pre">                               </span>// get an instruction pointer</div><div><span class="" style="white-space:pre">                              </span>Instruction* ins_temp = &*i; </div><div><span class="" style="white-space:pre">                          </span>//create a call instruction and insert it before every instruction</div>
<div><span class="" style="white-space:pre">                            </span>CallInst *call_print = CallInst::Create(call_print,paramArrayRef,"",ins_temp);</div><div><span class="" style="white-space:pre">                           </span></div><div><span class="" style="white-space:pre">                           </span>DEBUG(errs()<<"insert an instruction:"<<*call_print<<"\n");</div>
<div><br></div><div><span class="" style="white-space:pre">                   </span>}</div><div><span class="" style="white-space:pre">                  </span></div><div><br></div><div><span class="" style="white-space:pre">                  </span>return true;</div>
<div><span class="" style="white-space:pre">            </span>}</div><div><span class="" style="white-space:pre">  </span>};</div><div><span class="" style="white-space:pre"> </span></div><div><span class="" style="white-space:pre">   </span>char call_print::ID = 1;</div>
<div><span class="" style="white-space:pre">    </span>// register the printCode class: </div><div>  //  - give it a command-line argument (printCode)</div><div>  //  - a name ("print code")</div><div>  //  - a flag saying that we don't modify the CFG</div>
<div>  //  - a flag saying this is not an analysis pass</div><div>  RegisterPass<call_print> X("call_print", "call print func",</div><div><span class="" style="white-space:pre">                     </span>   false, false);</div>
<div><br></div><div>}</div></div><div><br></div><div>I successfully compile it .but when I use the call_print.so to transform the test .bc file like this:</div><div><br></div><div>opt -load /home/king/llvm/Release+Asserts/lib/call_print.so -call_print <test_sum.bc> test_sum.call.bc -debug<br>
</div><div><br></div><div>It failed with such information:</div><div><br></div><div><div> /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.</div>
</div><div><br></div><div>Can anyone tell me what the problem is ? And whether I wrote the pass right ?</div><div>Thank you!</div><div><br></div><div><br></div></div>