diff options
-rw-r--r-- | compile.c | 44 |
1 files changed, 36 insertions, 8 deletions
@@ -478,6 +478,7 @@ static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor, const NODE *n static int iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); +static int iseq_optimize_after_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl); @@ -1467,6 +1468,7 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) debugs("[compile step 4.1 (iseq_set_sequence)]\n"); if (!iseq_set_sequence(iseq, anchor)) return COMPILE_NG; + iseq_optimize_after_set_sequence(iseq, anchor); if (compile_debug > 5) dump_disasm_list(FIRST_ELEMENT(anchor)); @@ -2856,6 +2858,20 @@ ci_argc_set(const rb_iseq_t *iseq, const struct rb_callinfo *ci, int argc) } static int +iseq_peephole_optimize_after_set_sequence(rb_iseq_t *iseq, LINK_ELEMENT *list) +{ + INSN *const iobj = (INSN *)list; + + optimize_checktype(iseq, iobj); + + if (IS_INSN_ID(iobj, jump) || IS_INSN_ID(iobj, leave)) { + remove_unreachable_chunk(iseq, iobj->link.next); + } + + return COMPILE_OK; +} + +static int iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt) { INSN *const iobj = (INSN *)list; @@ -2893,7 +2909,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * LABEL2 directly */ replace_destination(iobj, diobj); - remove_unreachable_chunk(iseq, iobj->link.next); goto again; } else if (IS_INSN_ID(diobj, leave)) { @@ -2967,9 +2982,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal ELEM_REPLACE(&piobj->link, &popiobj->link); } } - if (remove_unreachable_chunk(iseq, iobj->link.next)) { - goto again; - } } /* @@ -3002,10 +3014,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal } } - if (IS_INSN_ID(iobj, leave)) { - remove_unreachable_chunk(iseq, iobj->link.next); - } - if (IS_INSN_ID(iobj, branchif) || IS_INSN_ID(iobj, branchnil) || IS_INSN_ID(iobj, branchunless)) { @@ -3542,6 +3550,26 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) return COMPILE_OK; } +static int +iseq_optimize_after_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) +{ + LINK_ELEMENT *list; + const int do_peepholeopt = ISEQ_COMPILE_DATA(iseq)->option->peephole_optimization; + int rescue_level = 0; + + list = FIRST_ELEMENT(anchor); + + while (list) { + if (IS_INSN(list)) { + if (do_peepholeopt) { + iseq_peephole_optimize_after_set_sequence(iseq, list); + } + } + list = list->next; + } + return COMPILE_OK; +} + #if OPT_INSTRUCTIONS_UNIFICATION static INSN * new_unified_insn(rb_iseq_t *iseq, |