为什么 llvm 被认为不适合实现 JIT?
许多动态语言实现(或想要实现)JIT 编译器以加快其执行时间。不可避免地,花生画廊里的人会问为什么他们不使用 LLVM。答案通常是“LLVM 不适合构建 JIT”。 (例如,Armin Rigo 的评论此处。)
为什么 LLVM 不适合构建 JIT?
注意:我知道LLVM有自己的JIT。如果LLVM以前不适合,但现在适合,请说一下有什么变化。我不是在谈论在 LLVM JIT 上运行 LLVM 字节码,而是在谈论使用 LLVM 库来实现动态语言的 JIT。
Many dynamic languages implement (or want to implement) a JIT Compiler in order to speed up their execution times. Inevitably, someone from the peanut gallery asks why they don't use LLVM. The answer is often, "LLVM is unsuitable for building a JIT." (For Example, Armin Rigo's comment here.)
Why is LLVM Unsuitable for building a JIT?
Note: I know LLVM has its own JIT. If LLVM used to be unsuitable, but now is suitable, please say what changed. I'm not talking about running LLVM Bytecode on the LLVM JIT, I'm talking about using the LLVM libraries to implement a JIT for a dynamic language.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我编写了 HLVM,这是一个高级虚拟机,具有丰富的静态类型系统,包括值类型,尾调用消除、通用打印、C FFI 和 POSIX 线程,支持静态和 JIT 编译。特别是,HLVM 提供令人难以置信的性能对于高级虚拟机。我什至使用 JIT 编译器实现了一个具有变体类型和模式匹配的类似 ML 的交互式前端,如 计算机代数演示。我所有与 HLVM 相关的工作加起来只需几周的时间(而且我不是计算机科学家,只是一个涉足者)。
我认为结果不言而喻,并明确证明 LLVM 完全适合 JIT 编译。
I wrote HLVM, a high-level virtual machine with a rich static type system including value types, tail call elimination, generic printing, C FFI and POSIX threads with support for both static and JIT compilation. In particular, HLVM offers incredible performance for a high-level VM. I even implemented an ML-like interactive front-end with variant types and pattern matching using the JIT compiler, as seen in this computer algebra demonstration. All of my HLVM-related work combined totals just a few weeks work (and I am not a computer scientist, just a dabbler).
I think the results speak for themselves and demonstrate unequivocally that LLVM is perfectly suitable for JIT compilation.
Unladen Swallow 事后博客文章中有一些关于 LLVM 的注释:
http://qinsb.blogspot.com/2011/03/unladen-swallow -retrospective.html 。
There are some notes about LLVM in the Unladen Swallow post-mortem blog post:
http://qinsb.blogspot.com/2011/03/unladen-swallow-retrospective.html .
启动时间较长是最大的抱怨 - 然而,如果您按照 Java 的做法并以解释器模式启动,并使用 LLVM 编译程序中最常用的部分,那么这并不是什么大问题。
此外,虽然互联网上到处都是这样的争论,但 Mono 已经成功地使用 LLVM 作为 JIT 编译器一段时间了现在(尽管值得注意的是,它默认使用他们自己的更快但效率较低的后端,并且他们还修改了 LLVM 的部分内容)。
对于动态语言,LLVM 可能不是合适的工具,因为它是为优化 C 和 C++ 等系统编程语言而设计的,这些语言是强/静态类型并支持非常低级的功能。一般来说,在 C 上执行的优化并不能真正使动态语言变得更快,因为您只是创建了一种运行缓慢系统的有效方法。现代动态语言 JIT 执行的操作包括内联仅在运行时才知道的函数,或者根据变量大多数时间的类型进行优化,而 LLVM 并非为此而设计。
It takes a long time to start up is the biggest complaint - however, this is not so much of an issue if you did what Java does and start up in interpreter mode, and use LLVM to compile the most used parts of the program.
Also while there are arguments like this scattered all over the internet, Mono has been using LLVM as a JIT compiler successfully for a while now (though it's worth noting that it defaults to their own faster but less efficient backend, and they also modified parts of LLVM).
For dynamic languages, LLVM might not be the right tool, just because it was designed for optimizing system programming languages like C and C++ which are strongly/statically typed and support very low level features. In general the optimizations performed on C don't really make dynamic languages fast, because you're just creating an efficient way of running a slow system. Modern dynamic language JITs do things like inlining functions that are only known at runtime, or optimizing based on what type a variable has most of the time, which LLVM is not designed for.
有一个关于使用 LLVM 作为 JIT 支持的演示,其中解决了许多关于它为什么不好的担忧,大部分似乎可以归结为人们将静态编译器构建为 JIT,而不是构建实际的 JIT。
There is a presentation on using LLVM as a JIT backened where the address many of the concerns raised as to why its bad, most of its seems to boil down to people building a static compiler as a JIT instead of building an actual JIT.
更新:截至 7/2014,LLVM 添加了一项名为“补丁点”的功能,用于支持 Safari 的 FTL JavaScript JIT。 这恰好涵盖了对原始问题中 int Armin Rigo 的评论所抱怨的用例。
Update: as of 7/2014, LLVM has added a feature called "Patch Points", which are used to support Polymorphic Inline Caches in Safari's FTL JavaScript JIT. This covers exactly the use case complained about int Armin Rigo's comment in the original question.
有关 LLVM IR 的更多详细信息,请参阅此处:LLVM IR是编译器 IR。
For a more detailed rant about the LLVM IR see here: LLVM IR is a compiler IR.