2015-08-22 48 views
0

我正在做一個儀器通行證。通行證應該以特別的方式修改給定的IR。所需的修改之一是在特定位置插入對功能的調用。 這是調用函數的簽名:創建一個callinst到一個外部函數

void myclass::foo(Function *f, BasicBlock* b) 

這個函數的原型是在foofile.h文件包括/ LLVM 和函數的定義是foofile.cpp文件中MCJIT文件夾。 並且在此文件夾下運行make可以正常工作,並且foofile.cpp編譯爲MCJIT.cpp,並且同一文件中的另一個函數可以正常工作。 不回到儀器通行證。如何在給定的IR中插入callinst給foo函數? 下面是插入該呼叫的片段:

Type* retTy = Type::getInt32Ty(C); 
FunctionType* FuncTy = FunctionType::get(retTy, false); 
PointerType* PtrToFuncTy = PointerType::get(FuncTy, 0); 
Constant *fun = M->getOrInsertFunction("foo", Type::getVoidTy(C), PtrToFuncTy, Type::getLabelTy(C), nullptr); 
Function *dofoo = cast<Function>(fun); 
Instruction* dofooCall = CallInst::Create(fun, Args2, "", bb); 

注意:Args2是含有2點值的指針的函數和basicblock一個ArrayList,bb是插入在呼叫中的basicblock

當我在給定的IR上運行使用op時,它會像這樣正確地生成聲明和呼叫:

聲明:

declare void @foo(i32()*, label) 

電話:

call void @foo(i32()* @main, label %for.cond) 

但是當我嘗試使用LLI,一切爆炸運行所產生的.ll文件!這是堆棧跟蹤之前的第2行:

Can't get register for value! 
UNREACHABLE executed at /home/marwayusuf/llvm-env/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:1158! 

我推斷問題是它找不到foo函數。如果這是問題,我該如何正確創建callinst?

回答

0

如果函數是類myclass的成員,它將有一個this指針作爲第一個參數。 C++方法名稱也具有名稱變形,因此它不使用符號「foo」。當使用mcjit時,它將IR降至機器碼,但它並不實際執行IR,所以在運行時不會傳遞llvm :: Function或llvm :: BasicBlock,因此即使您調用它,檢測函數也不起作用那。

+0

感謝您的幫助。但是,據我所知,當調用任何函數時,jit會查找該函數以查看它是否已經編譯過。這意味着函數對象仍然存在,這就是我需要的。此外,如果我想在沒有任何參數的情況下調用「foo」函數呢?我怎樣才能找到重名的名字? –

相關問題