rfc:jit-ir
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
rfc:jit-ir [2023/09/20 09:36] – created dmitry | rfc:jit-ir [2025/01/17 11:22] (current) – Link to correct merge commits, and fix typos/grammar theodorejb | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: A new JIT implementation based on IR Framework ====== | ====== PHP RFC: A new JIT implementation based on IR Framework ====== | ||
- | * Version: | + | * Version: |
* Date: 2023-09-20 | * Date: 2023-09-20 | ||
* Author: Dmitry Stogov, dmitry@php.net | * Author: Dmitry Stogov, dmitry@php.net | ||
- | * Status: | + | * Status: Accepted |
* First Published at: http:// | * First Published at: http:// | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | The first version of JIT for PHP was released in PHP-8.0 (https:// | + | The first version of JIT for PHP was released in PHP-8.0 (https:// |
- | A smarter JIT compiler with some Intermediate Representation was planned for a long time. The real work was started in January 2022. | + | A smarter JIT compiler with some Intermediate Representation was planned for a long time, and the real work was started in January 2022. |
- | This proposal is the result of that 1.75 years work. | + | This proposal is the result of these 1.75 years of work. |
===== Proposal ===== | ===== Proposal ===== | ||
- | I propose a new JIT implementation that is based on a separately developed [[https:// | + | I propose a new JIT implementation that is based on a separately developed [[https:// |
Instead of separate back-ends that generated x86 and AArch64 code, now we have a single back-end that constructs IR. | Instead of separate back-ends that generated x86 and AArch64 code, now we have a single back-end that constructs IR. | ||
- | Then this IR is passed to the Framework that performs machine independent optimisations, | ||
- | New JIT implementation will affect only a few core PHP developers who are involved in the JIT development or maintenance. | + | This IR is passed to the framework |
- | JIT is a self-containing subsystem and the changes in the implementation details (even big changes) don't affect others. | + | |
- | You may see that the proposed [[https:// | + | |
- | JIT is a quite complex subsystem. It can come without bugs, but I hope everything will be fixed. The early we merge this, the more time we have until the release. | + | On the other hand, sometimes |
- | The main goal of separate IR Framework | + | The new JIT implementation will affect only a few core PHP developers who are involved in the JIT development |
- | I won' | + | JIT is a self-contained subsystem, and the changes in the implementation details (even big changes) don' |
+ | |||
+ | The proposed [[https:// | ||
+ | |||
+ | At the current state the PR doesn' | ||
+ | |||
+ | JIT is a quite complex subsystem. Its first implementation will likely have bugs, but I am confident that these can be addressed. We have more time to fix potential issues the sooner this proposal passes, and the patch is merged. | ||
+ | |||
+ | The main goal of a separate | ||
+ | |||
+ | The necessary part of the IR Framework is embedded into the PHP source tree, and won't introduce any new external dependencies. | ||
+ | |||
+ | The details of the IR framework are complex. This [[https:// | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | There is no any BC breaks. | + | |
+ | There are no BC breaks | ||
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
+ | |||
next (master branch) | next (master branch) | ||
Line 37: | Line 48: | ||
==== Performance ==== | ==== Performance ==== | ||
- | In the current state the new PHP JIT implements exactly the same set of PHP related features and optimizations as the old one. | ||
- | Anyway, because of IR Framework optimizations and smarter Register Allocator, new JIT produces a bit faster (5-10%) and smaller code. | ||
- | This is visible on **bench.php** and **micro_bench.php**. Speed of the real-life applications is not affected. | ||
- | Compilation | + | The current new PHP JIT implements exactly the same set of PHP related features and optimizations as the old one. |
- | Anyway, this is quite good result for an Optimizing JIT compiler. In my tests PHP with new JIT may produce ~15MB of native code per second. | + | |
+ | Because the IR Framework provides more optimizations and has a smarter Register Allocator, the JIT produces a bit faster (5-10%) and smaller code. | ||
+ | |||
+ | This is visible with **bench.php** and **micro_bench.php**. The speed of real-life applications is not affected. | ||
+ | |||
+ | The compilation speed of the Tracing JIT is almost the same. The compilation speed of the Function JIT is up to 4 times slower | ||
+ | |||
+ | This is quite a good result for an Optimizing JIT compiler. In my tests, PHP with the new JIT may produce ~15MB of native code per second. | ||
==== Zend VM ==== | ==== Zend VM ==== | ||
- | On JIT supported platforms (x86, x86_64, AArch64) HYBRID VM interpreter starts to save and restore all the persistent CPU registers at **execute_ex()** prologue and epilogue. This allows elimination of the similar save/ | + | |
+ | On JIT supported platforms (x86, x86_64, AArch64), the HYBRID VM interpreter starts to save and restore all the persistent CPU registers at **execute_ex()** prologue and epilogue. | ||
+ | |||
+ | This allows elimination of the similar save/ | ||
==== To Opcache ==== | ==== To Opcache ==== | ||
- | JIT is implemented as a part of opcache, so the PR changes the build process for opcache. | + | |
- | Nothing else is affected. | + | JIT is implemented as a part of Opcache, so the PR changes the build process for Opcache. |
+ | No other changes are present. | ||
==== php.ini Defaults ==== | ==== php.ini Defaults ==== | ||
- | The PR doesn' | + | |
- | It adds few new IR related JIT debugging capabilities that may be enabled through **opcache.jit_debug** directive bits. | + | The PR does not introduce new php.ini |
+ | |||
+ | It adds few new IR related JIT debugging capabilities that may be enabled through **opcache.jit_debug** directive bits: | ||
* 0x01000000 - print the initial IR graph right after construction | * 0x01000000 - print the initial IR graph right after construction | ||
- | * 0x02000000 - print the final IR graph right before code emmision | + | * 0x02000000 - print the final IR graph right before code emission |
* 0x04000000 - print Control Flow Graph | * 0x04000000 - print Control Flow Graph | ||
* 0x08000000 - print information about Live Ranges and Allocated Registers | * 0x08000000 - print information about Live Ranges and Allocated Registers | ||
* 0x10000000 - print IR graph after Sparse Conditional Constants Propagation pass | * 0x10000000 - print IR graph after Sparse Conditional Constants Propagation pass | ||
- | * 0x20000000 - print IR graph after Global Code Motion and linearisation | + | * 0x20000000 - print IR graph after Global Code Motion and linearization |
* 0x40000000 - print IR graph after Register Allocation pass | * 0x40000000 - print IR graph after Register Allocation pass | ||
- | * 0x80000000 - anotate | + | * 0x80000000 - annotate |
==== To SAPIs ==== | ==== To SAPIs ==== | ||
+ | |||
SAPIs are not affected. | SAPIs are not affected. | ||
==== To Existing Extensions ==== | ==== To Existing Extensions ==== | ||
+ | |||
PHP extensions are not affected. | PHP extensions are not affected. | ||
==== New Constants ==== | ==== New Constants ==== | ||
+ | |||
There are no new constants. | There are no new constants. | ||
===== Open Issues ===== | ===== Open Issues ===== | ||
- | Should we keep the old implementation of the JIT for a while? | + | |
+ | Should we keep the old implementation of the JIT for a while, or change the patch to replace it straight away? | ||
===== Unaffected PHP Functionality ===== | ===== Unaffected PHP Functionality ===== | ||
- | JIT is developed as a self-contained feature and it doesn' | + | |
+ | JIT is developed as a self-contained feature, and doesn' | ||
===== Future Scope ===== | ===== Future Scope ===== | ||
- | Usage of IR opens the door for more powerful optimizations. | + | |
+ | The usage of IR opens the door for more powerful optimizations. | ||
+ | |||
+ | The other part is PHP specific (for example, | ||
+ | |||
+ | It is also possible to support new JIT targets | ||
+ | |||
+ | Finally, we may try to completely avoid the manual IR construction in JIT. We may introduce a single formal specification for VM instructions in a C-like language, convert it to IR and then use partial evaluation to generate VM and JIT handlers (similar to Truffle). | ||
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
- | Merge the new JIT implementation into PHP master? | + | |
+ | Voting opened 2023-10-06 and closes 2023-10-19. | ||
+ | |||
+ | <doodle title=" | ||
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
+ | |||
+ | |||
+ | Secondary vote: Should we keep the old JIT implementation for a while or remove it right after merge? | ||
+ | |||
+ | Note, that old implementation is not going to be tested (by CI) and we can't guarantee its functionality anyway. | ||
+ | |||
+ | <doodle title=" | ||
+ | * Yes | ||
+ | * No | ||
+ | </ | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== | ||
+ | |||
- https:// | - https:// | ||
- | - All CI tests (including nightly workflow) | + | - All CI tests (including nightly workflow) passed: https:// |
===== Implementation ===== | ===== Implementation ===== | ||
- | After the project is implemented, | + | |
- | - the version(s) it was merged into | + | |
- | | + | |
- | - a link to the PHP manual entry for the feature | + | |
- | | + | |
===== References ===== | ===== References ===== | ||
- | https:// | ||
- | ===== Rejected Features ===== | + | https:// |
- | Keep this updated with features that were discussed on the mail lists. | + | |
rfc/jit-ir.1695202597.txt.gz · Last modified: 2023/09/20 09:36 by dmitry