aboutsummaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-04-23 12:51:18 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-04-23 12:51:18 +0000
commit20f8daba67b2249f478b9be56a83a3c7e30110e7 (patch)
tree500c3db5760df21923ef38162c0f853beaf1c752 /compile.c
parent988ccdbb1894073b25f20c4091dc74c4d379a95f (diff)
downloadruby-20f8daba67b2249f478b9be56a83a3c7e30110e7.tar.gz
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
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/compile.c b/compile.c
index 2a089e8cdd..6a7f0ede40 100644
--- a/compile.c
+++ b/compile.c
@@ -2646,7 +2646,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
optimize_checktype(iseq, iobj);
if (IS_INSN_ID(iobj, jump)) {
- INSN *niobj, *diobj, *piobj;
+ INSN *niobj, *diobj, *piobj, *dniobj;
diobj = (INSN *)get_destination_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);
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;
/*
* jump LABEL
@@ -2693,12 +2696,19 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
*/
/* replace */
unref_destination(iobj, 0);
- iobj->insn_id = BIN(leave);
+ iobj->insn_id = diobj->insn_id;
iobj->operand_size = 0;
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 */
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;
}
else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 &&