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

ruby-changes:49502

From: nobu <ko1@a...>
Date: Fri, 5 Jan 2018 23:23:29 +0900 (JST)
Subject: [ruby-changes:49502] nobu:r61617 (trunk): compile.c: remove more unreachable chunk

nobu	2018-01-05 23:23:22 +0900 (Fri, 05 Jan 2018)

  New Revision: 61617

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61617

  Log:
    compile.c: remove more unreachable chunk
    
    * compile.c (remove_unreachable_chunk): remove beyond labels to be
      removed.

  Modified files:
    trunk/compile.c
Index: compile.c
===================================================================
--- compile.c	(revision 61616)
+++ compile.c	(revision 61617)
@@ -2330,25 +2330,48 @@ replace_destination(INSN *dobj, INSN *no https://github.com/ruby/ruby/blob/trunk/compile.c#L2330
     if (!dl->refcnt) ELEM_REMOVE(&dl->link);
 }
 
+static LABEL*
+find_destination(INSN *i)
+{
+    int pos, len = insn_len(i->insn_id);
+    for (pos = 0; pos < len; ++pos) {
+	if (insn_op_types(i->insn_id)[pos] == TS_OFFSET) {
+	    return (LABEL *)OPERAND_AT(i, pos);
+	}
+    }
+    return 0;
+}
+
 static int
 remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
 {
     LINK_ELEMENT *first = i, *end;
+    int *unref_counts = 0, nlabels = ISEQ_COMPILE_DATA(iseq)->label_no;
 
     if (!i) return 0;
-    while (i) {
+    unref_counts = ALLOCA_N(int, nlabels);
+    MEMZERO(unref_counts, int, nlabels);
+    end = i;
+    do {
+	LABEL *lab;
 	if (IS_INSN(i)) {
-	    if (IS_INSN_ID(i, jump) || IS_INSN_ID(i, leave)) {
+	    if (IS_INSN_ID(i, leave)) {
+		end = i;
 		break;
 	    }
+	    else if ((lab = find_destination((INSN *)i)) != 0) {
+		if (lab->unremovable) break;
+		unref_counts[lab->label_no]++;
+	    }
 	}
 	else if (IS_LABEL(i)) {
-	    if (((LABEL *)i)->unremovable) return 0;
-	    if (((LABEL *)i)->refcnt > 0) {
+	    lab = (LABEL *)i;
+	    if (lab->unremovable) return 0;
+	    if (lab->refcnt > unref_counts[lab->label_no]) {
 		if (i == first) return 0;
-		i = i->prev;
 		break;
 	    }
+	    continue;
 	}
 	else if (IS_TRACE(i)) {
 	    /* do nothing */
@@ -2357,9 +2380,8 @@ remove_unreachable_chunk(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L2380
 	    LABEL *dest = ((ADJUST *)i)->label;
 	    if (dest && dest->unremovable) return 0;
 	}
-	i = i->next;
-    }
-    end = i;
+	end = i;
+    } while ((i = i->next) != 0);
     i = first;
     do {
 	if (IS_INSN(i)) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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