Transferred from our internal repo since this discussion doesn't need to be private and it might be something we want to address in ZJIT.
Originally posted by @rwstauner:
We have several peephole optimizations for calling methods on new arrays to avoid the allocations (like [a, b, c].hash).
Ufuk had the idea that if we could similarly optimize [self.a, self.b] == [other.a, other.b] this could be a nice pattern for defining equality checks for custom classes.
Searching the instruction list for the second newarray call could get gnarly,
but it does help that you know the size of the first array.
If you limit the search to simple things like getlocal and send argc:0 (or getinstancevariable in case they do the other array before the self array) and find X of them followed by newarray followed by == we could at least optimize the simplest forms.
$ make -sj miniruby && ./miniruby --dump=insns,-opt -e 'def ==(other) = [a, @b] == [other.a, other.b]'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,45)>
0000 definemethod :==, == ( 1)[Li]
0003 putobject :==
0005 leave
== disasm: #<ISeq:==@-e:1 (1,0)-(1,45)>
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] other@0<Arg>
0000 putself ( 1)[Ca]
0001 send <calldata!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0004 getinstancevariable :@b, <is:0>
0007 newarray 2
0009 getlocal other@0, 0
0012 send <calldata!mid:a, argc:0, ARGS_SIMPLE>, nil
0015 getlocal other@0, 0
0018 send <calldata!mid:b, argc:0, ARGS_SIMPLE>, nil
0021 newarray 2
0023 send <calldata!mid:==, argc:1, ARGS_SIMPLE>, nil
0026 leave [Re]
Transferred from our internal repo since this discussion doesn't need to be private and it might be something we want to address in ZJIT.
Originally posted by @rwstauner:
We have several peephole optimizations for calling methods on new arrays to avoid the allocations (like
[a, b, c].hash).Ufuk had the idea that if we could similarly optimize
[self.a, self.b] == [other.a, other.b]this could be a nice pattern for defining equality checks for custom classes.Searching the instruction list for the second newarray call could get gnarly,
but it does help that you know the size of the first array.
If you limit the search to simple things like
getlocalandsend argc:0(orgetinstancevariablein case they do the other array before the self array) and find X of them followed by newarray followed by==we could at least optimize the simplest forms.