LLVM万花筒教程在本地外部失败 [英] LLVM Kaleidoscope tutorial failing on local extern
问题描述
我正在完成 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屋!