On Sat, Apr 25, 2020 at 6:44 PM tyson andre <tysonandre...@hotmail.com>
wrote:

> Hi internals,
>
> I was wondering if the maintainers of the Opcache Jit would be open to
> work on optimizing functions such as intdiv(), fdiv(), and spl_object_id()
> in the JIT to assembly code when it was safe to do so.
> These functions have simple C implementations, so the performance overhead
> of calling PHP functions in the generated assembly
> would be noticeable compared to emitting optimized assembly.
>
> I'd expect that it'd be safe to do so under the following circumstances:
>
> - All arguments are Compiled Variables(CV) in the opcodes (i.e. $var)
>   (
> http://nikic.github.io/2017/04/14/PHP-7-Virtual-machine.html#variable-types
> )
> - The types and count of the function arguments are known to be strictly
> correct, e.g.
>   - Opcache infers they will not throw a TypeError or emit undefined
> variable warnings
>   - maybe strictly accept floats but not integers for fdiv
> - The return value of the expression won't throw
>   (e.g. don't perform this optimization for `$y = spl_object_id($x)` when
> a CV is the return value)
> - The function in question exists and is not disabled.
>
> For example, these operands would be seen by the JIT for this sequence of
> opcodes
>
> ```php
> /*
> 0000 CV0($x) = RECV 1
> 0001 INIT_FCALL 1 96 string("spl_object_id")
> 0002 SEND_VAR CV0($x) 1
> 0003 V2 = DO_ICALL
> 0004 T1 = INIT_ARRAY 1 (packed) CV0($x) V2
> 0005 RETURN T1
> */
> function create_set(stdClass $x) : array {
>     return [spl_object_id($x) => $x];
> }
> ```
>
> I expect it to be technically feasible to check for the sequence of
> opcodes INIT_FCALL, SEND_VAR (repeated), and DO_ICALL, in
> ext/opcache/jit/zend_jit.c. The resulting assembly would be smaller and
> much faster.
> (this would be done before emitting any assembly - skip over the opcodes
> for INIT_ARRAY and SEND_VAR and DO_ICALL)
>
> - What do the maintainers of the JIT module think of this idea?
>   (e.g. are there concerns about this making it harder to understand the
> JIT codebase, adding potential bugs, or slowing down the generation of
> assembly)
> - Are there any general guidelines (or talks/articles) you'd recommend for
> new contributors to the Opcache JIT? I couldn't find a README and
> https://wiki.php.net/rfc/jit doesn't seem to make recommendations that
> apply to my question.
>
> ```
> // core fdiv C implementation (does not throw for a divisor of 0)
>         RETURN_DOUBLE(dividend / divisor);
> // core of spl_object_id C implementation
>         RETURN_LONG((zend_long)Z_OBJ_HANDLE_P(obj));
> ```
>
> I started looking into this because I work on an application that heavily
> uses spl_object_id()
> and would see a small performance benefit from this,
> and was reminded of this when looking at the get_resource_id() proposal.
> (
> https://github.com/phan/phan/search?q=spl_object_id&unscoped_q=spl_object_id
> )
>
> Thanks,
> - Tyson
>

Hi Tyson,

Our general approach to this is to first add a VM opcode for the operation,
which will also provide a benefit if the JIT is not used. There's already
plenty of those, see ZEND_STRLEN for example. Adding JIT support for the
opcode would then be the natural second step.

There aren't any hard rules for when this should be done, but I believe
having some evidence that the operation is both common and performance
critical would be good.

Nikita

Reply via email to