ruby-changes:40486
From: nobu <ko1@a...>
Date: Sat, 14 Nov 2015 15:26:33 +0900 (JST)
Subject: [ruby-changes:40486] nobu:r52567 (trunk): compile.c: remove unused labels
nobu 2015-11-14 15:26:15 +0900 (Sat, 14 Nov 2015) New Revision: 52567 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52567 Log: compile.c: remove unused labels * compile.c (iseq_label_data): manage reference count. * compile.c (iseq_peephole_optimize): remove unreferred labels which may disturb optimization. Modified files: trunk/compile.c Index: compile.c =================================================================== --- compile.c (revision 52566) +++ compile.c (revision 52567) @@ -48,6 +48,7 @@ typedef struct iseq_label_data { https://github.com/ruby/ruby/blob/trunk/compile.c#L48 int sc_state; int set; int sp; + int refcnt; } LABEL; typedef struct iseq_insn_data { @@ -190,8 +191,10 @@ r_value(VALUE value) https://github.com/ruby/ruby/blob/trunk/compile.c#L191 ADD_ELEM((seq), (LINK_ELEMENT *) \ new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1))) +#define LABEL_REF(label) ((label)->refcnt++) + /* add an instruction with label operand (alias of ADD_INSN1) */ -#define ADD_INSNL(seq, line, insn, label) ADD_INSN1(seq, line, insn, label) +#define ADD_INSNL(seq, line, insn, label) (ADD_INSN1(seq, line, insn, label), LABEL_REF(label)) #define ADD_INSN2(seq, line, insn, op1, op2) \ ADD_ELEM((seq), (LINK_ELEMENT *) \ @@ -253,6 +256,9 @@ r_value(VALUE value) https://github.com/ruby/ruby/blob/trunk/compile.c#L256 VALUE _e = rb_ary_new3(5, (type), \ (VALUE)(ls) | 1, (VALUE)(le) | 1, \ (VALUE)(iseqv), (VALUE)(lc) | 1); \ + if (ls) LABEL_REF(ls); \ + if (le) LABEL_REF(le); \ + if (lc) LABEL_REF(lc); \ rb_ary_push(iseq->compile_data->catch_table_ary, freeze_hide_obj(_e)); \ } while (0) @@ -915,6 +921,7 @@ new_label_body(rb_iseq_t *iseq, long lin https://github.com/ruby/ruby/blob/trunk/compile.c#L921 labelobj->label_no = iseq->compile_data->label_no++; labelobj->sc_state = 0; labelobj->sp = -1; + labelobj->refcnt = 0; return labelobj; } @@ -1873,6 +1880,26 @@ get_prev_insn(INSN *iobj) https://github.com/ruby/ruby/blob/trunk/compile.c#L1880 return 0; } +static void +unref_destination(INSN *iobj) +{ + LABEL *lobj = (LABEL *)OPERAND_AT(iobj, 0); + --lobj->refcnt; + if (!lobj->refcnt) REMOVE_ELEM(&lobj->link); +} + +static void +replace_destination(INSN *dobj, INSN *nobj) +{ + VALUE n = OPERAND_AT(nobj, 0); + LABEL *dl = (LABEL *)OPERAND_AT(dobj, 0); + LABEL *nl = (LABEL *)n; + --dl->refcnt; + ++nl->refcnt; + OPERAND_AT(dobj, 0) = n; + if (!dl->refcnt) REMOVE_ELEM(&dl->link); +} + static int iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt) { @@ -1900,11 +1927,12 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L1927 * => * LABEL: */ + unref_destination(iobj); REMOVE_ELEM(&iobj->link); } else if (iobj != diobj && diobj->insn_id == BIN(jump)) { if (OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0)) { - OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0); + replace_destination(iobj, diobj); goto again; } } @@ -1925,6 +1953,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L1953 INSN *popiobj = new_insn_core(iseq, iobj->line_no, BIN(pop), 0, 0); /* replace */ + unref_destination(iobj); REPLACE_ELEM((LINK_ELEMENT *)iobj, (LINK_ELEMENT *)eiobj); INSERT_ELEM_NEXT((LINK_ELEMENT *)eiobj, (LINK_ELEMENT *)popiobj); iobj = popiobj; @@ -1949,7 +1978,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L1978 if (niobj == (INSN *)get_destination_insn(piobj)) { piobj->insn_id = (piobj->insn_id == BIN(branchif)) ? BIN(branchunless) : BIN(branchif); - OPERAND_AT(piobj, 0) = OPERAND_AT(iobj, 0); + replace_destination(piobj, iobj); REMOVE_ELEM(&iobj->link); } } @@ -1972,7 +2001,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2001 for (;;) { if (nobj->insn_id == BIN(jump)) { - OPERAND_AT(iobj, 0) = OPERAND_AT(nobj, 0); + replace_destination(iobj, nobj); } else if (prev_dup && nobj->insn_id == BIN(dup) && !!(nobj = (INSN *)nobj->link.next) && @@ -1993,7 +2022,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2022 * dup * if L2 */ - OPERAND_AT(iobj, 0) = OPERAND_AT(nobj, 0); + replace_destination(iobj, nobj); } else break; nobj = (INSN *)get_destination_insn(nobj); @@ -3595,6 +3624,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L3624 ADD_INSN(ret, nd_line(tempnode), dup); ADD_INSN2(ret, nd_line(tempnode), opt_case_dispatch, literals, elselabel); + LABEL_REF(elselabel); } ADD_SEQ(ret, cond_seq); @@ -5948,6 +5978,7 @@ register_label(rb_iseq_t *iseq, struct s https://github.com/ruby/ruby/blob/trunk/compile.c#L5978 else { label = (LABEL *)tmp; } + LABEL_REF(label); return label; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/