This is a good start to the conversation - PHP needs a fast JIT (& it can have a good one too), but it doesn't entirely help that the strict typing RFC has foundered.<p>About five years ago, I started to work on a basic block PHP JIT using libjit, mostly out of frustration of dealing with the dull progress I was making with pecl APC's speed & concurrency issues.<p>The JIT started off simple and then went nowhere for four months because the primary requirement for register allocator (and the jit_type_t SSA) is an actual type - the zval_ variables cannot sit on a register.<p>There's an old sys-con paper[1] by my guru, who found a way to build a direct threaded JIT which could run in partial JIT mode without working out how to handle complex exception handling or making non-inlined function calls out of the JIT (the engine was called CVM).<p>The reason my PHP JIT failed to do anything relevant was due to the opcode structure of PHP which triggers a halting problem version of type-checking which both JVM and .NET IL avoids. In this context, it should be mentioned that the .NET IL bytecode is actually polymorphic (i.e JVM has iadd/ladd/fadd, while the IL has just add & add.ovf).<p>The types of the variables on the ->op1 and ->op2 needn't be the same type in PHP, so that each opcode is actually prefixed by a routing to the right binary operator table [2].<p>This means that the memory bandwidth overheads and branch prediction mechanisms on the JIT generated code would be nearly exactly the same as the regular C implementation of the engine.<p>HHVM works around the exact same problem by forcing the type specification as a HACK-LANG type system, which allows it to really go ahead and optimize the pointless type-checking.<p>PHP needn't entirely force strict-typing across the board, but at least needs to prevent different codepaths from ending up at the same opcode with vastly different types.<p>That one detail is effectively stopping a sane JIT from being built for PHP - because it neither a register machine (like perl6/parrod), nor a stack machine (like JVM, .NET or Python), but an opcode sequence more tied together like a rough DAG connected via ->op1, ->op2, ->result, along with the TMPVAR indexes.<p>That gets insanely complex to process very quickly as you have to traverse every-path including branch-backs to generate type traces through it - the loop could execute once where $a is an int and again with $a being a float.<p>All that said, this is an AOT engine - it does use LLVM, but is mostly entirely compiled before running (like old HipHop C++ compiler) and then does not by-pass the overheads introduced by the lack of type verifiability for an opcode.<p>[1] - <a href="http://www2.sys-con.com/itsg/virtualcd/dotnet/archives/0103/weatherley/index.html" rel="nofollow">http://www2.sys-con.com/itsg/virtualcd/dotnet/archives/0103/...</a>
[2] - <a href="https://github.com/php/php-src/blob/master/Zend/zend_vm_gen.php#L687" rel="nofollow">https://github.com/php/php-src/blob/master/Zend/zend_vm_gen....</a>