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 <XrXr@users.noreply.github.com>
This commit is contained in:
Aaron Patterson 2021-01-26 15:49:21 -08:00 коммит произвёл Aaron Patterson
Родитель 296a2cab07
Коммит 938e027cdf
1 изменённых файлов: 26 добавлений и 0 удалений

Просмотреть файл

@ -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;
}