我正在开发类JIT工具,以下是代码:
Obj doSomething(Obj o, Selector sel){
...
}
我有一个指向这个函数的指针,我的问题是如何将指针包装成LLVM:Value
,以便我可以使用IRBuilder.CreateCall
将其插入我的IR中。我需要做什么?
我正在开发类JIT工具,以下是代码:
Obj doSomething(Obj o, Selector sel){
...
}
我有一个指向这个函数的指针,我的问题是如何将指针包装成LLVM:Value
,以便我可以使用IRBuilder.CreateCall
将其插入我的IR中。我需要做什么?
boo()
函数:#include <stdio.h>
typedef int (*callback)(const char*);
static int boo(callback print, const char *str) { return print(str); }
int main() { return boo(puts, "hello world"); }
我相信我的解决方案至少能适用于LLVM 9到14版本,基于对这两个版本的测试。
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
int main()
{
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
auto C = std::make_unique<llvm::LLVMContext>();
auto M = std::make_unique<llvm::Module>("boomodule", *C);
const auto ArgType = llvm::Type::getInt8Ty(*C)->getPointerTo();
std::vector<llvm::Type *> PutsArgs{ArgType};
llvm::FunctionType *PutsType =
llvm::FunctionType::get(llvm::Type::getInt32Ty(*C), PutsArgs, false);
llvm::FunctionType *FT =
llvm::FunctionType::get(llvm::Type::getInt32Ty(*C),
{PutsType->getPointerTo(), ArgType}, false);
{
llvm::Function *TheFunction =
llvm::Function::Create(FT, llvm::Function::ExternalLinkage,
"boo", M.get());
{
llvm::IRBuilder<> builder(llvm::BasicBlock::Create(*C, "entry",
TheFunction));
auto Arg = TheFunction->arg_begin();
llvm::FunctionCallee FC{PutsType, Arg++};
builder.CreateRet(builder.CreateCall(FC, Arg));
}
assert(!llvm::verifyFunction(*TheFunction, &llvm::errs()));
// TheFunction->dump();
}
llvm::ExitOnError ExitOnErr;
auto J = ExitOnErr(llvm::orc::LLJITBuilder().create());
ExitOnErr(J->addIRModule
(llvm::orc::ThreadSafeModule(std::move(M), std::move(C))));
auto BooAddr = ExitOnErr(J->lookup("boo"));
typedef int (*callback)(const char*);
auto boo =
reinterpret_cast<int(*)(callback, const char*)>(BooAddr.getAddress());
return boo(puts, "hello world");
}
// c++ lljit.cc $(llvm-config --cxxflags --ldflags --system-libs --libs core)
我找到了一些其他的例子,其中使用CreateAlloca()
来存储和加载函数指针。在我的应用程序中,我将通过参数传递一个函数指针数组给生成的函数。
(我理解你的问题是:我有一个指向LLVM函数的C++指针,我需要创建一个对它进行调用的调用,如果我理解错了,请在帖子中或下面的评论中澄清)
大多数LLVM类都派生自llvm::Value
,当您执行以下操作时:
llvm::Function *theFunction = llvm::Function::Create(...);
llvm::Function 是 llvm::Value
的子类,您可以在 CreateCall
中使用它。
Value *result = Builder.CreateCall(theFunction, ...); // This is the call instruction
Type::getVoidTy
。似乎网上没有任何好的示例展示如何做到这一点。如果可能的话,你可以使用指针(最好是void *)和一个包装函数来简化情况。 - antipattern