diff options
author | Aaron Patterson <[email protected]> | 2021-01-26 15:49:21 -0800 |
---|---|---|
committer | Aaron Patterson <[email protected]> | 2021-02-16 14:00:36 -0800 |
commit | 938e027cdf019ff2cb6ee8a7229e6d9a4d8fc953 (patch) | |
tree | f4d9b768659b56f12118fbfefc7cff9f958170f9 /compile.c | |
parent | 296a2cab07ce530809ee74dee61180fbb3ca6f91 (diff) |
Eliminate useless catch tables and nops from lambdas
Before this commit:
```
$ ruby --dump=insn -e '1.times { |x| puts x }'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,22)> (catch: FALSE)
== catch table
| catch type: break st: 0000 ed: 0004 sp: 0000 cont: 0004
| == disasm: #<ISeq:block in <main>@-e:1 (1,8)-(1,22)> (catch: FALSE)
| == catch table
| | catch type: redo st: 0001 ed: 0006 sp: 0000 cont: 0001
| | catch type: next st: 0001 ed: 0006 sp: 0000 cont: 0006
| |------------------------------------------------------------------------
| local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
| [ 1] x@0<Arg>
| 0000 nop ( 1)[Bc]
| 0001 putself [Li]
| 0002 getlocal_WC_0 x@0
| 0004 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
| 0006 leave [Br]
|------------------------------------------------------------------------
0000 putobject_INT2FIX_1_ ( 1)[Li]
0001 send <calldata!mid:times, argc:0>, block in <main>
0004 leave
```
After this commit:
```
> ruby --dump=insn -e '1.times { |x| puts x }'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,22)> (catch: FALSE)
0000 putobject_INT2FIX_1_ ( 1)[Li]
0001 send <calldata!mid:times, argc:0>, block in <main>
0004 leave
== disasm: #<ISeq:block in <main>@-e:1 (1,8)-(1,22)> (catch: FALSE)
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0<Arg>
0000 putself ( 1)[LiBc]
0001 getlocal_WC_0 x@0
0003 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0005 leave
```
Fixes [ruby-core:102418] [Feature #17613]
Co-Authored-By: Alan Wu <[email protected]>
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4125
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 26 |
1 files changed, 26 insertions, 0 deletions
@@ -1497,6 +1497,12 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) debugs("[compile step 6 (update_catch_except_flags)] \n"); update_catch_except_flags(iseq->body); + debugs("[compile step 6.1 (remove unused catch tables)] \n"); + if (!iseq->body->catch_except_p && iseq->body->catch_table) { + xfree(iseq->body->catch_table); + iseq->body->catch_table = NULL; + } + #if VM_INSN_INFO_TABLE_IMPL == 2 if (iseq->body->insns_info.succ_index_table == NULL) { debugs("[compile step 7 (rb_iseq_insns_info_encode_positions)] \n"); @@ -3525,6 +3531,12 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) list = FIRST_ELEMENT(anchor); + int do_block_optimization = 0; + + if (iseq->body->type == ISEQ_TYPE_BLOCK && !iseq->body->catch_except_p) { + do_block_optimization = 1; + } + while (list) { if (IS_INSN(list)) { if (do_peepholeopt) { @@ -3536,6 +3548,13 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) if (do_ou) { insn_operands_unification((INSN *)list); } + + if (do_block_optimization) { + INSN * item = (INSN *)list; + if (IS_INSN_ID(item, jump)) { + do_block_optimization = 0; + } + } } if (IS_LABEL(list)) { switch (((LABEL *)list)->rescued) { @@ -3550,6 +3569,13 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) } list = list->next; } + + if (do_block_optimization) { + LINK_ELEMENT * le = FIRST_ELEMENT(anchor)->next; + if (IS_INSN(le) && IS_INSN_ID((INSN *)le, nop)) { + ELEM_REMOVE(le); + } + } return COMPILE_OK; } |