ruby-changes:40632
From: nobu <ko1@a...>
Date: Sun, 22 Nov 2015 16:53:45 +0900 (JST)
Subject: [ruby-changes:40632] nobu:r52711 (trunk): compile.c: move logop DCE
nobu 2015-11-22 16:53:37 +0900 (Sun, 22 Nov 2015) New Revision: 52711 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52711 Log: compile.c: move logop DCE * compile.c (iseq_peephole_optimize): remove unreachable code chunk after jump/leave. * parse.y: move dead code elimination of logical operation to compile.c. not to warn logical operation of literal constants. Modified files: trunk/ChangeLog trunk/compile.c trunk/parse.y trunk/test/ruby/test_syntax.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 52710) +++ ChangeLog (revision 52711) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Nov 22 16:53:34 2015 Nobuyoshi Nakada <nobu@r...> + + * compile.c (iseq_peephole_optimize): remove unreachable code + chunk after jump/leave. + + * parse.y: move dead code elimination of logical operation to + compile.c. not to warn logical operation of literal constants. + Sun Nov 22 16:37:10 2015 Nobuyoshi Nakada <nobu@r...> * compile.c (iseq_peephole_optimize): eliminate always/never Index: compile.c =================================================================== --- compile.c (revision 52710) +++ compile.c (revision 52711) @@ -1906,6 +1906,30 @@ replace_destination(INSN *dobj, INSN *no https://github.com/ruby/ruby/blob/trunk/compile.c#L1906 } static int +remove_unreachable_chunk(LINK_ELEMENT *i) +{ + int removed = 0; + while (i) { + if (i->type == ISEQ_ELEMENT_INSN) { + switch (INSN_OF(i)) { + case BIN(jump): + case BIN(branchif): + case BIN(branchunless): + case BIN(branchnil): + unref_destination((INSN *)i); + default: + break; + } + } + else break; + REMOVE_ELEM(i); + removed = 1; + i = i->next; + } + return removed; +} + +static int iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt) { INSN *iobj = (INSN *)list; @@ -1935,11 +1959,11 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L1959 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)) { - replace_destination(iobj, diobj); - goto again; - } + else if (iobj != diobj && diobj->insn_id == BIN(jump) && + OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0)) { + replace_destination(iobj, diobj); + remove_unreachable_chunk(iobj->link.next); + goto again; } else if (diobj->insn_id == BIN(leave)) { /* @@ -1988,6 +2012,13 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2012 REMOVE_ELEM(&iobj->link); } } + else if (remove_unreachable_chunk(iobj->link.next)) { + goto again; + } + } + + if (iobj->insn_id == BIN(leave)) { + remove_unreachable_chunk(iobj->link.next); } if (iobj->insn_id == BIN(branchif) || @@ -3788,6 +3819,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L3819 LABEL *redo_label = iseq->compile_data->redo_label = NEW_LABEL(line); /* redo */ LABEL *break_label = iseq->compile_data->end_label = NEW_LABEL(line); /* break */ LABEL *end_label = NEW_LABEL(line); + LABEL *adjust_label = NEW_LABEL(line); LABEL *next_catch_label = NEW_LABEL(line); LABEL *tmp_label = NULL; @@ -3802,6 +3834,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L3834 tmp_label = NEW_LABEL(line); ADD_INSNL(ret, line, jump, tmp_label); } + ADD_LABEL(ret, adjust_label); ADD_INSN(ret, line, putnil); ADD_LABEL(ret, next_catch_label); ADD_INSN(ret, line, pop); @@ -3829,6 +3862,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L3862 } ADD_LABEL(ret, end_label); + ADD_ADJUST_RESTORE(ret, adjust_label); if (node->nd_state == Qundef) { /* ADD_INSN(ret, line, putundef); */ Index: parse.y =================================================================== --- parse.y (revision 52710) +++ parse.y (revision 52711) @@ -9747,15 +9747,6 @@ new_if_gen(struct parser_params *parser, https://github.com/ruby/ruby/blob/trunk/parse.y#L9747 { if (!cc) return right; cc = cond0(parser, cc); - switch (nd_type(cc)) { - case NODE_NIL: - case NODE_FALSE: - return right; - case NODE_TRUE: - case NODE_LIT: - case NODE_STR: - return left; - } return NEW_IF(cc, left, right); } @@ -9763,11 +9754,7 @@ static NODE* https://github.com/ruby/ruby/blob/trunk/parse.y#L9754 logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right) { value_expr(left); - if (!left) { - if (!in_defined && type == NODE_AND) return 0; - /* make NODE_OR not to be "void value expression" */ - } - else if ((enum node_type)nd_type(left) == type) { + if (left && (enum node_type)nd_type(left) == type) { NODE *node = left, *second; while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) { node = second; @@ -9775,20 +9762,6 @@ logop_gen(struct parser_params *parser, https://github.com/ruby/ruby/blob/trunk/parse.y#L9762 node->nd_2nd = NEW_NODE(type, second, right, 0); return left; } - else if (!in_defined) { - switch (nd_type(left)) { - case NODE_NIL: - case NODE_FALSE: - if (type == NODE_AND) return left; - break; - case NODE_TRUE: - case NODE_LIT: - case NODE_STR: - if (type != NODE_AND) return left; - nd_set_type(left, NODE_TRUE); - break; - } - } return NEW_NODE(type, left, right, 0); } Index: test/ruby/test_syntax.rb =================================================================== --- test/ruby/test_syntax.rb (revision 52710) +++ test/ruby/test_syntax.rb (revision 52711) @@ -633,6 +633,18 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L633 assert_valid_syntax("a\n&.foo") end + def test_no_warning_logop_literal + assert_warning("") do + eval("true||raise;nil") + end + assert_warning("") do + eval("false&&raise;nil") + end + assert_warning("") do + eval("''||raise;nil") + end + end + private def not_label(x) @result = x; @not_label ||= nil end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/