diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-08-25 03:33:32 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-08-25 03:33:32 +0000 |
commit | ed3a575b594ad734b403f7ffc4f100cae707604c (patch) | |
tree | ab04a62358793e33fbd7b5b877e2bff9bc9cdb9d /compile.c | |
parent | 5ccf7b0610c1268d3931fcd58b3a84becc5e1cb1 (diff) | |
download | ruby-ed3a575b594ad734b403f7ffc4f100cae707604c.tar.gz |
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.c | 23 |
1 files changed, 20 insertions, 3 deletions
@@ -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; |