LLVM万花筒教程在本地外部失败 [英] LLVM Kaleidoscope tutorial failing on local extern

查看:337
本文介绍了LLVM万花筒教程在本地外部失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在完成 LLVM万花筒教程.除了 local externs(与数学函数之类的东西相反)之外,其他所有东西都工作正常.

I am working through the LLVM Kaleidoscope tutorial. Everything is working fine except for local externs (as opposed to things like the math functions).

[c34n10 kaleidoscope] ./toy
ready> extern sin(x); sin(1);
ready> Read extern:
declare double @sin(double)

ready> ready> Evaluated to 0.841471
ready> extern putchard(x); putchard(120);
ready> Read extern:
declare double @putchard(double)

ready> ready> Failure value returned from cantFail wrapped call
UNREACHABLE executed at /gpfs/loomis/project/fas/manohar/emb99/llvm/include/llvm/Support/Error.h:732!
Aborted (core dumped)

根据本教程,

putchard在我的代码中声明为

putchard is declared in my code, per the tutorial, as

/// putchard - putchar that takes a double and returns 0.
extern "C" DLLEXPORT double putchard(double X) {
  fputc((char)X, stderr);
  return 0;
}

其他在线帖子表明,此问题可能是由于未使用-rdynamic进行编译而引起的,但我是.

Other posts online suggest that this issue could be caused by not compiling with -rdynamic, but I am.

使用以下代码发生实际错误

The actual error is occuring with the following code

auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
assert(ExprSymbol && "Function not found");

// cast to double-returning function
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());

和对GDB的一些调查显示,ExprSymbol.getAddress()hasError标志为true,这就是cantFail失败的原因.至于为什么设置该标志,我很茫然.

and some investigation with GDB reveals that the hasError flag of ExprSymbol.getAddress() is true, which is why the cantFail is failing. As to why that flag is set, I'm at a loss.

函数本身似乎没有问题:在GDB中,我可以成功运行call putchard(120),因此该符号肯定存在于可执行文件中.

It appears not to be an issue with the function itself: from within GDB, I can successfully run call putchard(120), so the symbol definitely exists in the executable.

最后,我的makefile看起来像

Finally, my makefile looks like

LIBS=core orcjit native analysis executionengine instcombine object runtimedyld scalaropts support
FLAGS=`llvm-config --cxxflags --ldflags --system-libs --libs $(LIBS)`

%: %.cpp
        clang++ -v -g3 -O0 $^ -o $@ $(FLAGS) -rdynamic

推荐答案

我在LLVM 8中遇到了完全相同的问题.

I ran into exactly the same issue in LLVM 8.

问题是符号解析器不会尝试在本地进程的地址中找到请求的符号,并且Expected<T>需要强制检查错误.

The problem is the symbol resolver doesn't try to find the requested symbol in local process's address, and an Expected<T> requires mandatory checking for errors.

我稍微改变了KaleidoscopeJIT.h以克服它.

I changed KaleidoscopeJIT.h a bit to get over it.

用这个替换KaleidoscopeJIT的构造函数:

Replace the KaleidoscopeJIT's constructor with this one:

KaleidoscopeJIT()
      : Resolver(createLegacyLookupResolver(
            ES,
            [this](const std::string &Name) {
              auto symbol = ObjectLayer.findSymbol(Name, true);
              if (!symbol)
              {
                if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
                  return JITSymbol(SymAddr, JITSymbolFlags::Exported);
              }
              return symbol;
            },
            [](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
        TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
        ObjectLayer(ES,
                    [this](VModuleKey) {
                      return ObjLayerT::Resources{
                          std::make_shared<SectionMemoryManager>(), Resolver};
                    }),
        CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
    llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
  }

唯一的变化是,如果在调用ObjectLayer.findSymbol()后未找到任何符号,它将转向RTDyldMemoryManager::getSymbolAddressInProcess()查找并创建JITSymbol对象.

The only change is, if no symbol is found after calling ObjectLayer.findSymbol(), it will turn to RTDyldMemoryManager::getSymbolAddressInProcess() to find and create the JITSymbol object.

这篇关于LLVM万花筒教程在本地外部失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆