summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-08-25 03:33:32 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-08-25 03:33:32 +0000
commited3a575b594ad734b403f7ffc4f100cae707604c (patch)
treeab04a62358793e33fbd7b5b877e2bff9bc9cdb9d /compile.c
parent5ccf7b0610c1268d3931fcd58b3a84becc5e1cb1 (diff)
compile.c: useless jump elimination
* compile.c (iseq_peephole_optimize): eliminate useless if/unless just before jump. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59655 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/compile.c b/compile.c
index 74e20e9e05..2ae62b03f5 100644
--- a/compile.c
+++ b/compile.c
@@ -866,7 +866,6 @@ INSERT_ELEM_PREV(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
}
}
-#if 0
/*
* elemX, elem1, elemY => elemX, elem2, elemY
*/
@@ -882,7 +881,6 @@ REPLACE_ELEM(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
elem1->next->prev = elem2;
}
}
-#endif
static void
REMOVE_ELEM(LINK_ELEMENT *elem)
@@ -2211,7 +2209,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 &&
(IS_INSN_ID(piobj, branchif) ||
IS_INSN_ID(piobj, branchunless))) {
- if (niobj == (INSN *)get_destination_insn(piobj)) {
+ INSN *pdiobj = (INSN *)get_destination_insn(piobj);
+ if (niobj == pdiobj) {
/*
* useless jump elimination (if/unless destination):
* if L1
@@ -2231,6 +2230,24 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
replace_destination(piobj, iobj);
REMOVE_ELEM(&iobj->link);
}
+ else if (diobj == pdiobj) {
+ /*
+ * useless jump elimination (if/unless before jump):
+ * L1:
+ * ...
+ * if L1
+ * jump L1
+ *
+ * ==>
+ * L1:
+ * ...
+ * pop
+ * jump L1
+ */
+ INSN *popiobj = new_insn_core(iseq, iobj->line_no,
+ BIN(pop), 0, 0);
+ REPLACE_ELEM(&piobj->link, &popiobj->link);
+ }
}
else if (remove_unreachable_chunk(iseq, iobj->link.next)) {
goto again;