为什么llvm被认为不适合实现JIT?

为什么llvm被认为不适合实现JIT?,llvm,jit,Llvm,Jit,许多动态语言实现(或想要实现)JIT编译器以加快其执行时间。不可避免地,有人从花生画廊问他们为什么不使用LLVM。答案通常是,“LLVM不适合构建JIT。”(例如,Armin Rigo的评论) 为什么LLVM不适合构建JIT? 注意:我知道LLVM有自己的JIT。如果LLVM过去不合适,但现在合适,请说明发生了什么变化。我不是说在LLVM JIT上运行LLVM字节码,我是说使用LLVM库实现动态语言的JIT。Unladen Swallow post-mortem博客文章中有一些关于LLVM的注释

许多动态语言实现(或想要实现)JIT编译器以加快其执行时间。不可避免地,有人从花生画廊问他们为什么不使用LLVM。答案通常是,“LLVM不适合构建JIT。”(例如,Armin Rigo的评论)

为什么LLVM不适合构建JIT?


注意:我知道LLVM有自己的JIT。如果LLVM过去不合适,但现在合适,请说明发生了什么变化。我不是说在LLVM JIT上运行LLVM字节码,我是说使用LLVM库实现动态语言的JIT。

Unladen Swallow post-mortem博客文章中有一些关于LLVM的注释:

不幸的是,处于当前状态的LLVM实际上是作为静态编译器优化器和后端设计的。LLVM代码生成和优化很好,但成本很高。这些优化都是为处理由静态类C语言生成的IR而设计的。优化Python的大多数重要优化都需要高级知识来了解程序在以前的迭代中是如何执行的,而LLVM并没有帮助我们做到这一点


启动需要很长时间是最大的抱怨——然而,如果您像Java那样,在解释器模式下启动,并使用LLVM编译程序中最常用的部分,那么这就不是什么问题了

另外,尽管在互联网上到处都有类似的争论,但他们已经成功地将LLVM用作JIT编译器一段时间了(尽管值得注意的是,它默认为自己的更快但效率更低的后端,并且他们还修改了LLVM的部分)

对于动态语言,LLVM可能不是正确的工具,仅仅是因为它被设计用于优化系统编程语言,如C和C++,它们是强/静态类型的,支持非常低的特征。一般来说,在C上执行的优化并不能真正提高动态语言的速度,因为您只是创建了一种运行速度较慢的系统的有效方法。现代动态语言JIT做了一些事情,比如只在运行时才知道的内联函数,或者根据变量在大多数情况下的类型进行优化,而LLVM不是为这种类型而设计的。

有一个关于将LLVM用作JIT的讨论,其中解决了许多关于它为什么不好的问题,大多数问题似乎归结为人们将静态编译器构建为JIT,而不是构建实际的JIT

为什么LLVM不适合构建JIT

我写了一个高级虚拟机,它具有丰富的静态类型系统,包括值类型、尾部调用消除、通用打印、CFI和POSIX线程,支持静态和JIT编译。特别是,HLVM提供了高级VM。我甚至使用JIT编译器实现了一个类似ML的交互式前端,其中包含变量类型和模式匹配,如图所示。我所有与HLVM相关的工作加起来只有几周的工作(我不是一个计算机科学家,只是一个涉猎者)


我认为结果不言自明,并明确证明LLVM非常适合JIT编译。

有关LLVM IR的更多详细信息,请参见此处:。

更新:自2014年7月起,LLVM添加了一个名为“补丁点”的功能,这篇文章中用于支持多态性内联缓存的内容正好涵盖了在原始问题中抱怨int Armin Rigo评论的用例。

Hmm。。。说答案是“因为它太慢了。”-1 LLVM并不被认为不适合实现JIT。也许你可以写一篇关于你的I-implemented-a-JIT-with-LLVM-and-it-was-awesome体验的文章?对于我的下一个技巧,我将告诉铁厨师如何制作华夫饼。(拍了拍自己)没关系。在另一个问题上更糟糕的是,尽管我是唯一一个用函数式语言编写了几个低延迟商业应用程序的回答者,但我还是得到了4张反对票!许多人来到LLVM时,似乎都梦想着轻触开关,它会神奇地瞬间优化生成的代码,但事实并非如此。垃圾进来,垃圾出去。如果您希望LLVM生成快速代码,那么您必须自己生成优化的IR。像Python这样的动态类型语言将受到特别严重的打击,因为任何升级/装箱都会破坏LLVM优化阶段所依赖的静态类型信息。你的工作是关于静态类型的函数式语言,我听到的抱怨(链接在帖子中)来自于实现动态类型命令式/面向对象语言的人。我想知道类型或功能性是否有更大的影响。静态类型和功能性样式都有很大的影响,但您可以解决不匹配的问题。LLVM自己的
mem2reg
optimization pass实际上将值类型(int、float等)上的命令式代码从内存操作转换为纯功能的单一静态赋值代码(HLVM自然生成的类型)。动态类型更难,因为它不可能获得可预测的良好性能,但一些简单的解决方案应该是有效的,例如将所有值表示为非固定联合,或者根据需要为所有可能的参数类型组合编译函数。这东西还存在吗?它被用于哪些语言?我已经多年没有积极开发HLVM了,而且据说它没有用户。Julia实际上实现了你的后一个建议,性能非常好。C/C++不是强类型的。强类型意味着每个值都与不能改变的类型永久关联,这对于大多数动态语言来说是正确的,但是C和C++的解释性转换不是正确的。这是否意味着它是弱类型的?@alternative:你是说你可以给Haskell一块原始字节,并告诉它开始将其视为,例如,
IO()