llvm JIT将库添加到模块

时间:2018-01-05 00:03:11

标签: c++ llvm jit

我正在使用一个使用LLVM的JIT。该语言有一个用C ++编写的小运行时,我使用clang

编译成LLVM IR
clang++ runtime.cu --cuda-gpu-arch=sm_50 -c -emit-llvm

然后加载* .bc文件,生成额外的IR,并在运行中执行。 CUDA的原因是我想在运行时添加一些GPU加速。但是,这会引入CUDA特定的外部函数,这些函数会产生错误,例如:

LLVM ERROR: Program used external function 'cudaSetupArgument' which could not be resolved!

正如here所讨论的,通常在编译程序时包含适当的库来解决这个问题:

g++ main.c cmal.o -L/usr/local/cuda/lib64 -lcudart 

但是,我不确定如何使用LLVM在JITed模块中包含库。我发现this这个问题表明以前可以将库添加到JIT中的模块,如下所示:

[your module]->addLibrary("m");

不幸的是,这已被弃用。现在有人能告诉我最好的方法吗?如果我需要提供更多信息,请告诉我们!

此外,我不确定这是否是将GPU卸载合并到我的JIT中的最佳方法,所以如果有人能指出我更好的方法那么请执行:)

谢谢!

编辑:我使用的是LLVM 5.0,而我使用的JIT引擎来自llvm/ExecutionEngine/ExecutionEngine.h,更具体地说,我是这样创建的:

EngineBuilder EB(std::move(module));
ExecutionEngine *EE = EB.create(targetMachine);

1 个答案:

答案 0 :(得分:6)

您需要明确地告知您的JIT引擎其他符号。

如果他们在动态库中(dylibsodll),那么您可以致电

sys::DynamicLibrary::LoadLibraryPermanently("path_to_some.dylib")

带有动态库的路径。

如果符号位于目标文件或存档中,则需要更多工作:您需要将它们加载到内存中并使用其API添加到ExecutionEngine

以下是目标文件的示例:

std::string objectFileName("some_object_file.o");

ErrorOr<std::unique_ptr<MemoryBuffer>> buffer =
  MemoryBuffer::getFile(objectFileName.c_str());

if (!buffer) {
  // handle error
}

Expected<std::unique_ptr<ObjectFile>> objectOrError =
  ObjectFile::createObjectFile(buffer.get()->getMemBufferRef());

if (!objectOrError) {
  // handle error
}

std::unique_ptr<ObjectFile> objectFile(std::move(objectOrError.get()));

auto owningObject = OwningBinary<ObjectFile>(std::move(objectFile),
                                             std::move(buffer.get()));

executionEngine.addObjectFile(std::move(owningObject));

对于归档,使用ObjectFile替换模板类型Archive,然后调用

executionEngine.addArchive(std::move(owningArchive));

最后。