【问题标题】:LLVM Kaleidoscope tutorial failing on local externLLVM Kaleidoscope 教程在本地外部失败
【发布时间】:2019-01-05 01:47:11
【问题描述】:

我正在处理LLVM Kaleidoscope tutorial。除了 local externs(与数学函数之类的东西相反)之外,一切都运行良好。

[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 - putchar that takes a double and returns 0.
extern "C" DLLEXPORT double putchard(double X) {
  fputc((char)X, stderr);
  return 0;
}

网上的其他帖子表明这个问题可能是由于没有使用-rdynamic编译造成的,但我是。

实际错误发生在以下代码中

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 标志为真,这就是 cantFail 失败的原因。至于为什么设置那个标志,我很茫然。

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

最后,我的 makefile 看起来像

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

【问题讨论】:

  • 嗨,baum,在使用教程中提到的 -Wl,--export-dynamic 进行编译时,我也遇到了同样的错误。您找到解决方案了吗?而且在教程中它被称为 mcjit 而不是 orcjit,你是如何找到正确的库的?
  • 您好,同路人。还没有解决办法。另外,我正在编译详细的 (-v) 并且 --export-dynamic 已经被包括在内(可能-rdynamic 正在这样做)。至于 mcjit/orcjit,我遇到了编译问题,并意识到我正在使用 orc 类,但从未包含这些库。我已经联系了 llvm-dev listserv;如果有人回信,我会在这里更新。
  • 谢谢,我也看到了有关在 llvm-dev 列表中记录您的邮件的错误消息的更新。我也遇到了同样的错误“找不到符号 {printd}”。
  • 这看起来是相关的。我也没有通过给出的测试用例:groups.google.com/forum/#!topic/llvm-dev/5XbVMI75OSA
  • @PreeJackie 您是否通过 SVN 安装了 LLVM 8?我正在尝试最新的稳定版本 (7.0.0)

标签: llvm extern


【解决方案1】:

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

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

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

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

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对象。

【讨论】:

  • 不再从事这个项目,因此无法确认结果。无论如何都接受,希望将来对其他人有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 2018-02-25
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多