compile.c: copy a short insn with leave

* compile.c (iseq_peephole_optimize): copy not only `leave`, with
  a non-operand instruction, which are not longer than `jump`.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63248 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2018-04-23 12:51:18 +00:00
Родитель 425118b898
Коммит 4cae5353c0
1 изменённых файлов: 14 добавлений и 4 удалений

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

@ -2646,7 +2646,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
optimize_checktype(iseq, iobj); optimize_checktype(iseq, iobj);
if (IS_INSN_ID(iobj, jump)) { if (IS_INSN_ID(iobj, jump)) {
INSN *niobj, *diobj, *piobj; INSN *niobj, *diobj, *piobj, *dniobj;
diobj = (INSN *)get_destination_insn(iobj); diobj = (INSN *)get_destination_insn(iobj);
niobj = (INSN *)get_next_insn(iobj); niobj = (INSN *)get_next_insn(iobj);
@ -2677,7 +2677,10 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
remove_unreachable_chunk(iseq, iobj->link.next); remove_unreachable_chunk(iseq, iobj->link.next);
goto again; goto again;
} }
else if (IS_INSN_ID(diobj, leave)) { else if (IS_INSN_ID(diobj, leave) ? !(dniobj = 0) :
(diobj->operand_size == 0 &&
(dniobj = (INSN *)get_next_insn(diobj)) != 0 &&
(IS_INSN_ID(dniobj, leave) || (dniobj = 0)))) {
INSN *pop; INSN *pop;
/* /*
* jump LABEL * jump LABEL
@ -2693,12 +2696,19 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
*/ */
/* replace */ /* replace */
unref_destination(iobj, 0); unref_destination(iobj, 0);
iobj->insn_id = BIN(leave); iobj->insn_id = diobj->insn_id;
iobj->operand_size = 0; iobj->operand_size = 0;
iobj->insn_info = diobj->insn_info; iobj->insn_info = diobj->insn_info;
if (dniobj) {
dniobj = new_insn_body(iseq, dniobj->insn_info.line_no, BIN(leave), 0);
ELEM_INSERT_NEXT(&iobj->link, &dniobj->link);
}
else {
dniobj = iobj;
}
/* adjust stack depth */ /* adjust stack depth */
pop = new_insn_body(iseq, diobj->insn_info.line_no, BIN(pop), 0); pop = new_insn_body(iseq, diobj->insn_info.line_no, BIN(pop), 0);
ELEM_INSERT_NEXT(&iobj->link, &pop->link); ELEM_INSERT_NEXT(&dniobj->link, &pop->link);
goto again; goto again;
} }
else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 && else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 &&