Skip to content

Optimize newarray == newarray to avoid allocations #770

Description

@k0kubun

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]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions