llvm jit windows 8.1



我正在VS 2013编译的windows 8.1上运行fibonacci演示。到目前为止,我解决了几个问题:1.对象文件格式不兼容-我在函数getDefaultFormat(const Triple&T)中为windows将Triple::COFF更改为Triple::ELF2.缺少asm打印机-我添加了InitializeNativeTargetAsmPrinter()3.内存保护-我手动将VirtualProtect设置为PAGE_EXECUTE(它没有设置,我不知道它应该如何工作)

现在我可以运行生成的代码,但它崩溃了,下面是反汇编的代码:000000EC4B890000推送rsi
000000EC4B890001推送rdi
000000EC4B890002推送rbx
000000EC4B890003子rsp,20小时
000000EC4B890007 mov esi,ecx
000000EC4B890009 cmp esi,2
000000 EC4B89000C jg 000000 EC4B 890015
000000EC4B89000E mov eax,1
00000EC4B890013 jmp 000000EC4B89002F
000000EC4B890015 lea ecx,[rsi-1]
000000EC4B890018 mov rbx,0
000000EC4B890022调用rbx
000000EC4B890024 mov edi,eax
000000EC4B890026添加esi,0FFFFFFFEh
000000EC4B890029 mov ecx,esi
000000EC4B89002B调用rbx
000000EC4B89002D添加eax,edi
000000EC4B89002F添加rsp,20小时
000000EC4B890033 pop-rbx
000000EC4B890034 pop-rdi
000000EC4B890035 pop-rsi
000000EC4B890036 ret

在地址000000EC4B890018上是指令mov rbx,0和紧接在该调用之后的rbx,这导致崩溃。还有另一件奇怪的事情,调用堆栈似乎被损坏了,在序言之后,调试器调用堆栈中有一些函数没有被调用。

这是IR:

define i32 @fib(i32 %AnArg) {
EntryBlock:
  %cond = icmp sle i32 %AnArg, 2
  br i1 %cond, label %return, label %recurse
return:                                           ; preds = %EntryBlock
  ret i32 1
recurse:                                          ; preds = %EntryBlock
  %arg = sub i32 %AnArg, 1
  %fibx1 = tail call i32 @fib(i32 %arg)
  %arg1 = sub i32 %AnArg, 2
  %fibx2 = tail call i32 @fib(i32 %arg1)
  %addresult = add i32 %fibx1, %fibx2
  ret i32 %addresult
}

我正在运行windows 8.1专业版LLVM是使用VS 2013社区版在x64配置中编译的我使用LLVM 3.6.0

注意:x86配置有效(除了版本中的解释器,它会崩溃)

我错过了什么吗?我应该为x64或COFF使用ELF吗(我认为它没有在JIT中实现)?

我正在着手一个大项目。性能很关键,我想在其中使用一个脚本,但它必须被修改。最重要的平台是Windows、Android和iOS。我担心llvm对这些平台的JIT支持。我知道llvm和clang在所有这些平台上都被广泛使用,但由于目前面临的问题,我对JIT不太确定。

我在使用Windows 8.1、Visual Studio 2013、LLVM 3.6.1(-elf hack)时遇到了完全相同的问题。JIT的代码未解析(mov reg,0x0),内存页无法执行(立即崩溃)。

问题是:JIT模块实际上并没有最终确定,我认为它可能来自-elf破解。为了解决这个问题,我必须在ExecutionEngine::getFunctionAddress(应该确保模块最终确定)和对JIT’ed代码的调用之间显式调用ExecutionEngine:finalizeObject

// Call the JIT'ed code
auto pCode = (BasicBlockCode)sm_pExecutionEngine->getFunctionAddress(pExecFunc->getName());
// NOTE: We must call this method explicitly since it seems getFunctionAddress won't call it
// -elf windows hack?
sm_pExecutionEngine->finalizeObject();
pCode(reinterpret_cast<u8*>(m_pCpuCtxt), reinterpret_cast<u8*>(m_pMemCtxt));

MC JIT还没有(尽管即将推出:http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20150216/261096.html)支持动态加载的COFF对象。

因此,如果您想要跨平台LLVM JIT,则需要检查您是否在Windows上运行,然后将目标三元组更改为附加"-elf"。

我对C++API不太熟悉,所以我放了一个例子(使用LLVM.NETC#绑定):

var platform = Environment.OSVersion.Platform;
if (platform == PlatformID.Win32NT) // On Windows, LLVM currently (3.6) does not support PE/COFF
{
   LLVM.SetTarget(mod, Marshal.PtrToStringAnsi(LLVM.GetDefaultTargetTriple()) + "-elf");
}

最新更新