[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]