为什么打给
jit->lookup("test");
命中失败的断言:“正在解决此职责范围之外的符号”?
当我以以下方式创建函数时会执行此操作:
define double @test() {
begin:
ret double 1.343000e+01
}
但是当我将函数创建为
时,它可以正常工作(即,在没有断言的情况下找到它)define void @test() {
begin:
ret void
}
这不是找不到函数“ test”的情况,如果我查找不存在的名称,它的行为会有所不同。
这是命中断言的代码:
ThreadSafeModule Create_M()
{
auto pCtx = make_unique<LLVMContext>();
LLVMContext& ctx = *pCtx;
auto pM = make_unique<Module>("myModule", ctx);
Module& M = *pM;
IRBuilder<> builder(ctx);
FunctionType* FT = FunctionType::get(Type::getDoubleTy(ctx),false);
Function* testFn = Function::Create(FT,
GlobalValue::LinkageTypes::ExternalLinkage, "test", M);
auto BB = BasicBlock::Create(ctx,"begin",testFn);
builder.SetInsertPoint(BB);
builder.CreateRet(ConstantFP::get(ctx,APFloat(13.43)));
outs() << M; // For debugging
return ThreadSafeModule(std::move(pM), std::move(pCtx));
}
int main()
{
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
// Create an LLJIT instance.
auto jit = ExitOnErr(LLJITBuilder().create());
auto M1 = Create_M();
ExitOnErr(jit->addIRModule(std::move(M1)));
auto testSym = ExitOnErr(jit->lookup("test"));
}
用这些行替换函数创建,没有问题:
FunctionType* FT = FunctionType::get(Type::getVoidTy(ctx),false);
Function* testFn = Function::Create(FT,
GlobalValue::LinkageTypes::ExternalLinkage, "test", M);
auto BB = BasicBlock::Create(ctx,"begin",testFn);
builder.SetInsertPoint(BB);
builder.CreateRetVoid();
我想了解断言的含义,为什么它在一种情况下而不在另一种情况下断言,以及我需要为(* double)()情况做些什么才能使其生效。我做了很多搜索有关LLVM责任集的文档的工作,但几乎没有发现。在https://llvm.org/docs/ORCv2.html处有人提及,但不足以让我解释该断言告诉我的内容。
我正在使用截至2019年8月20日的SVN存储库版本的LLVM,该版本基于Visual Studio 2017 15.9.6。
答案 0 :(得分:0)
这确实是Windows平台上ORC LLJIT中的错误。
在此处查看错误记录:
https://bugs.llvm.org/show_bug.cgi?id=44337
修正提交参考:
https://github.com/llvm/llvm-project/commit/84217ad66115cc31b184374a03c8333e4578996f
对于任何手动构建自定义JIT /编译器层堆栈的人(不使用LLJIT),您需要做的就是在发射ELF图像时强制弱符号自动声明。
if (JTMB.getTargetTriple().isOSBinFormatCOFF())
{
ObjectLayer.setAutoClaimResponsibilityForObjectSymbols(true);
}
如果设置,此ObjectLinkingLayer实例将声明对 由给定目标文件提供的任何符号,这些符号尚未存在 MaterializationResponsibility实例。
设置此标志将允许更高级别的程序表示(例如 LLVM IR)仅根据它们的一部分符号添加 提供,而无需编写中间层即可进行扫描和添加 附加符号。为了方便起见,这以诊断质量为代价 但是:如果所有符号都是预先枚举的,则冲突可能是 尽早发现并报告(通常是确定性的)。如果这 设置了此选项,可能无法检测到其他符号的冲突 直到很晚,检测可能取决于控制流程 JIT代码。小心使用。
答案 1 :(得分:0)
要解决此错误,请添加ObjectLinkingLayer.setAutoClaimResponsibilityForObjectSymbols(true);
例如:
auto jit = ExitOnErr(LLJITBuilder()
.setJITTargetMachineBuilder(std::move(JTMB))
.setObjectLinkingLayerCreator([&](ExecutionSession &ES, const Triple &TT) {
auto ll = make_unique<ObjectLinkingLayer>(ES,
make_unique<jitlink::InProcessMemoryManager>());
ll->setAutoClaimResponsibilityForObjectSymbols(true);
return move(ll);
})
.create());