![]() I hope this post proves valuable not only to JIT developers at large but also to those specifically involved in Ruby JIT development. This article provides an overview of the MIR-based JIT for CRuby and summarizes the results of the unfinished project, along with my ideas for further improving MIR-based JIT and YJIT performance. Given Shopify's strategic interest in CRuby JIT and the ample resources dedicated to this pursuit, the future of CRuby JIT is in capable hands. ![]() They are transitioning from direct machine code generation to generating internal representation (IR) and optimizing it as an intermediate step. The YJIT team has done an exemplary job, and their approach aligns well with the goal of further enhancing JIT performance. ![]() The success of YJIT led to a pivotal decision by my management team and me: to discontinue work on the MIR-based JIT for CRuby. Over the past six months, I have focused on an MIR-based JIT that compiles SIR, already specialized at the interpreter level. Employing RTL enhances the interpreter's performance, but it's not actually necessary for improving the performance of the MIR-based JIT. SIR, in addition to specialization, functions as a register transfer language (RTL), whereas the original VM instructions are stack-based. Specialization is achieved through basic block versioning invented by Maxime Chevalier-Boisvert and speculative techniques. Last year, I introduced specialization at the VM instruction level, introducing a new collection of specialized VM instructions known as SIR (specialized internal representation). In response, I accelerated the process by implementing different specializations at the instruction level of CRuby virtual machine ( VM), departing from the singular approach of MIR and incorporating the current state of the MIR JIT compiler. The introduction of Shopify YJIT for CRuby a couple of years ago disrupted my long-standing strategy. My intention was to leverage the power of MIR for a new CRuby JIT, forming a part of my long-term strategy. More detailed information on these objectives can be found in one of my previous blog posts. ![]() The long-term aspiration is to develop a meta-tracing JIT compiler for automatically generating JITs from a C-written interpreter. MIR should facilitate code specialization and execution trace optimizations. The ultimate objective of the MIR project is to simplify JIT implementation for dynamic programming languages. While the MIR project has made significant strides and is already employed for JIT implementations in various programming languages, it has yet to reach its culmination. This compiler aimed to achieve speeds 100 times faster than GCC and generate code with performance comparable to that produced by GCC with -O2 optimizations. Initially, I decided to create a universal lightweight JIT compiler based on a machine-independent medium internal representation ( MIR). Undaunted, I embarked on this ambitious multi-year project. It became clear that developing an effective JIT for CRuby was a multi-year endeavor requiring dedicated efforts from a select few. I dedicated a year of work to MJIT, gaining valuable experience and insights into the JIT requirements for CRuby. However, it struggled to enhance performance for many widely-used applications, such as Ruby on Rails. MJIT notably improved the performance of Optcarrot, a classic Ruby benchmark, by threefold. Takashi Kokubun adopted MJIT, improving it and integrating it into the CRuby release, where he continued to maintain it thereafter. To improve MJIT compilation speed, I employed precompiled headers and generated machine code in parallel with Ruby program execution. However, GCC proved to be slow as a JIT compiler. so files in the memory file system, subsequently loaded by a dynamic loader for execution. It was based on utilizing the GCC compiler, which generated machine code as. MJIT provided a rapid way to implement JIT for CRuby. My initial attempt to implement a CRuby JIT was MJIT (method based just-in-time compiler). A significant portion of this effort involved implementing the CRuby just-in-time (JIT) compiler. About six years ago, I began dedicating half of my work time to improving performance of CRuby, the de facto standard Ruby implementation. The major development of the GCC register allocator and instruction scheduler was completed quite some time ago, and these days, my main responsibility is maintaining these essential GCC components. I am a GCC compiler engineer, and for the past 15 years, I have primarily focused on the GCC register allocator and instruction scheduler.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |