首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与LLVM JIT (LLJIT)

与LLVM JIT (LLJIT)
EN

Stack Overflow用户
提问于 2022-09-16 08:47:25
回答 1查看 79关注 0票数 -1

我遵循一个使用LLVM编写JIT编译器的教程 (代码如下所示,并使用了最新版本的LLVM )。除了这一行(如果我对此函数进行注释,代码会编译):

代码语言:javascript
运行
复制
 return (T)symbol.get().getAddress();

这将产生以下错误:

代码语言:javascript
运行
复制
JIT.cpp:22:29: error: ‘std::remove_reference_t<llvm::orc::ExecutorAddr> {aka class llvm::orc::ExecutorAddr}’ has no member named ‘getAddress’
 return (T)symbol.get().getAddress();

代码

代码语言:javascript
运行
复制
#pragma once

#include <llvm/ExecutionEngine/Orc/LLJIT.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <memory>
#include <type_traits>

namespace FooLang
{
class JIT
{
private:
std::unique_ptr<llvm::orc::LLJIT> lljit;

public:
JIT(std::unique_ptr<llvm::orc::LLJIT> _lljit) : lljit(std::move(_lljit)) {}

void registerSymbols(
    llvm::function_ref<llvm::orc::SymbolMap(llvm::orc::MangleAndInterner)> symbolMap) {
    auto &mainJitDylib = this->lljit->getMainJITDylib();
    llvm::cantFail(mainJitDylib.define(
        absoluteSymbols(symbolMap(llvm::orc::MangleAndInterner(
            mainJitDylib.getExecutionSession(), this->lljit->getDataLayout())))));
}

template <typename T, typename = std::enable_if_t<std::is_pointer<T>::value && std::is_function<std::remove_pointer_t<T>>::value>>
llvm::Expected<T> lookup(const std::string &name)
{
    auto symbol = this->lljit->lookup(name);

    if (!symbol)
    {
        return symbol.takeError();
    }

    return (T)symbol.get().getAddress();
}

template <typename T, typename = std::enable_if_t<std::is_function<T>::value>>
inline llvm::Expected<T *> lookup(const std::string &name)
{
    return this->lookup<T *>(name);
}

static llvm::Expected<JIT> create(std::unique_ptr<llvm::Module> &module, std::unique_ptr<llvm::LLVMContext> &context)
{
    auto lljit = llvm::orc::LLJITBuilder().create();
    auto &jd = lljit.get()->getMainJITDylib();

    jd.addGenerator(llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess('_')));

    if (!lljit)
    {
        return lljit.takeError();
    }

    if (auto err = lljit.get()->addIRModule(llvm::orc::ThreadSafeModule(std::move(module), std::move(context))))
    {
        return std::move(err);
    }

    return JIT(std::move(lljit.get()));
}
};
 } // namespace FooLang

它的用途如下:

代码语言:javascript
运行
复制
int run(IRgen* ir_gen)
{
auto jit = JIT::create(ir_gen->module, ir_gen->llvm_context);

jit->registerSymbols(
    [&](llvm::orc::MangleAndInterner interner) {
        llvm::orc::SymbolMap symbolMap;
        // Add symbols here
        symbolMap[interner("printf")] = llvm::JITEvaluatedSymbol::fromPointer(printf);
        return symbolMap;
    });


auto entry = jit->lookup<int()>("main");
if (!entry)
{
    llvm::errs() << entry.takeError();
    return 1;
}

return entry.get()();
}
EN

回答 1

Stack Overflow用户

发布于 2022-09-16 22:45:34

在最近的更改中,auto symbol = this->llvmjit->lookup(name);将返回一个ExecutorAddr而不是一个JITEvaluatedSymbols,请参见:https://reviews.llvm.org/rG16dcbb53dc7968a3752661aac731172ebe0faf64

粘贴的代码返回模板参数类型T,不显示调用者,因此我无法看到您打算返回的内容。我的建议是,您可能想使用ExecutorAddr::toPtr,但我不能肯定。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73742249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档