Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug #20457] Do not remove final return node #10642

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

nobu
Copy link
Member

@nobu nobu commented Apr 26, 2024

This was an optimization for versions prior to 1.9 that traverse the AST at runtime.

This was an optimization for versions prior to 1.9 that traverse the
AST at runtime.
@tenderlove
Copy link
Member

I think this might require more work in compile.c (or maybe the peephole optimizer).

Given this code:

def foo
  a = 1
  if bar
    return a
  else
    return a
  end
end

The iseqs with Ruby master look like this:

== disasm: #<ISeq:foo@<compiled>:1 (1,0)-(8,3)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] a@0
0000 putobject_INT2FIX_1_                                             (   2)[LiCa]
0001 setlocal_WC_0                          a@0
0003 putself                                                          (   3)[Li]
0004 opt_send_without_block                 <calldata!mid:bar, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0006 branchunless                           11
0008 getlocal_WC_0                          a@0                       (   4)[Li]
0010 leave                                                            (   8)[Re]
0011 getlocal_WC_0                          a@0                       (   6)[Li]
0013 leave                                                            (   8)[Re]

On this branch they look like this:

== disasm: #<ISeq:foo@<compiled>:1 (1,0)-(8,3)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] a@0
0000 putobject_INT2FIX_1_                                             (   2)[LiCa]
0001 setlocal_WC_0                          a@0
0003 putself                                                          (   3)[Li]
0004 opt_send_without_block                 <calldata!mid:bar, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0006 branchunless                           13
0008 getlocal_WC_0                          a@0                       (   4)[Li]
0010 leave                                  [Re]
0011 putnil
0012 leave                                                            (   8)[Re]
0013 getlocal_WC_0                          a@0                       (   6)[Li]
0015 leave                                  [Re]
0016 putnil
0017 leave                                                            (   8)[Re]

@nobu
Copy link
Member Author

nobu commented Apr 28, 2024

With simpler code:

def foo(a) = return a

Master:

== disasm: #<ISeq:foo@-e:1 (1,0)-(1,21)>
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] a@0<Arg>
0000 getlocal_WC_0                          a@0                       (   1)[Ca]
0002 leave                                  [Re]

This patch:

== disasm: #<ISeq:foo@-e:1 (1,0)-(1,21)>
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] a@0<Arg>
0000 getlocal_WC_0                          a@0                       (   1)[Ca]
0002 leave                                  [Re]
0003 putnil
0004 leave                                  [Re]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants