[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:13

From: ko1 atdot.net
Date: 8 Jun 2005 13:33:02 -0000
Subject: [yarv-diff:13] r168 - trunk

Author: ko1
Date: 2005-06-08 22:33:00 +0900 (Wed, 08 Jun 2005)
New Revision: 168

Modified:
   trunk/ChangeLog
   trunk/compile.c
   trunk/test.rb
Log:
	* compile.c : add if/unless(L1) jump (L2) :L1 => unless/if(L2)
	optimize (condition reversal) and fix typo



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-06-08 03:03:49 UTC (rev 167)
+++ trunk/ChangeLog	2005-06-08 13:33:00 UTC (rev 168)
@@ -4,6 +4,12 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-06-08(Wed) 22:30:44 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* compile.c : add if/unless(L1) jump (L2) :L1 => unless/if(L2)
+	optimize (condition reversal) and fix typo
+
+
 2005-06-07(Tue) 08:29:41 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* yarvcore.c : fix to remove compiler warning

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2005-06-08 03:03:49 UTC (rev 167)
+++ trunk/compile.c	2005-06-08 13:33:00 UTC (rev 168)
@@ -264,6 +264,13 @@
   }
 }
 
+static void REMOVE_ELEM(struct iseq_link_element *elem){
+  elem->prev->next = elem->next;
+  if(elem->next){
+    elem->next->prev = elem->prev;
+  }
+}
+
 /*
 #define APPEND_LINKED_LIST(list1, list2) \
 { \
@@ -935,6 +942,30 @@
   return list;
 }
 
+static struct iseq_link_element *
+get_next_insn(struct insn_object *iobj){
+  struct iseq_link_element *list = iobj->link.next;
+  while(list){
+    if(list->type == ISEQ_ELEMENT_INSN){
+      return list;
+    }
+    list = list->next;
+  }
+  return 0;
+}
+
+static struct iseq_link_element *
+get_prev_insn(struct insn_object *iobj){
+  struct iseq_link_element *list = iobj->link.prev;
+  while(list){
+    if(list->type == ISEQ_ELEMENT_INSN){
+      return list;
+    }
+    list = list->prev;
+  }
+  return 0;
+}
+
 static void iseq_optimize(VALUE self, struct link_anchor *anchor, VALUE ary){
   struct iseq_link_element *list;
   /*
@@ -951,9 +982,10 @@
   list = FIRST_ELEMENT(anchor);
   while(list){
     if(list->type == ISEQ_ELEMENT_INSN){
-      struct insn_object *niobj, *iobj = (struct insn_object *)list;
+      struct insn_object *niobj, *piobj, *iobj = (struct insn_object *)list;
       if(iobj->insn_id == BIN(jump)){
         niobj = (struct insn_object*)get_destination_insn(iobj);
+        
         if(niobj->insn_id == BIN(jump)){
           OPERAND_OF_RAW(iobj, 0) = OPERAND_OF_RAW(niobj, 0);
           continue;
@@ -962,14 +994,36 @@
           VALUE endinsn = new_insn(BIN(end), iobj->line_no, niobj->operands);
           struct insn_object *eiobj;
           GetInsnVal(endinsn, eiobj);
-          
+
           /* protect for GC */
           rb_ary_push(ary, endinsn);
-          
+
           /* replace */
           REPLACE_ELEM((struct iseq_link_element *)iobj,
                        (struct iseq_link_element *)eiobj);
         }
+        /*
+         *   if   L1
+         *   jump L2
+         * L1:
+         *   ...
+         * L2:
+         *
+         * ==>
+         *   unless L2
+         * L1:
+         *   ...
+         * L2:
+         */
+        else if ((piobj = (struct insn_object*)get_prev_insn(iobj)) != 0 &&
+                 (piobj->insn_id == BIN(if) ||
+                  piobj->insn_id == BIN(unless))){
+          if(get_next_insn(iobj) == get_destination_insn(piobj)){
+            piobj->insn_id = (piobj->insn_id == BIN(if)) ? BIN(unless) : BIN(if);
+            OPERAND_OF_RAW(piobj, 0) = OPERAND_OF_RAW(iobj, 0);
+            REMOVE_ELEM(&iobj->link);
+          }
+        }
       }
     }
     list = list->next;
@@ -1246,27 +1300,27 @@
   return iseqobj->local_size;
 }
 
-static VALUE compile_branch_conditon(VALUE self, NODE *cond,
+static VALUE compile_branch_condition(VALUE self, NODE *cond,
                                      VALUE then_label, VALUE else_label){
   VALUE ret = NEW_SEQ();
   
   switch(nd_type(cond)){
   case NODE_NOT:
-    ret = compile_branch_conditon(self, cond->nd_body, else_label, then_label);
+    ret = compile_branch_condition(self, cond->nd_body, else_label, then_label);
     break;
 
   case NODE_AND:{
     VALUE label = NEW_LABEL(nd_line(cond));
-    ADD_SEQ  (ret, compile_branch_conditon(self, cond->nd_1st, label, else_label));
+    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_1st, label, else_label));
     ADD_LABEL(ret, label);
-    ADD_SEQ  (ret, compile_branch_conditon(self, cond->nd_2nd, then_label, else_label));
+    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_2nd, then_label, else_label));
     break;
   }
   case NODE_OR:{
     VALUE label = NEW_LABEL(nd_line(cond));
-    ADD_SEQ  (ret, compile_branch_conditon(self, cond->nd_1st, then_label, label));
+    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_1st, then_label, label));
     ADD_LABEL(ret, label);
-    ADD_SEQ  (ret, compile_branch_conditon(self, cond->nd_2nd, then_label, else_label));
+    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_2nd, then_label, else_label));
     break;
   }
   default:
@@ -1548,7 +1602,7 @@
     else_label = NEW_LABEL(nd_line(node));
     end_label  = NEW_LABEL(nd_line(node));
 
-    cond_seq = compile_branch_conditon(self, node->nd_cond, then_label, else_label);
+    cond_seq = compile_branch_condition(self, node->nd_cond, then_label, else_label);
     then_seq = COMPILE_("then", node->nd_body, poped);
     else_seq = COMPILE_("else", node->nd_else, poped);
 
@@ -1731,13 +1785,13 @@
     
     ADD_LABEL(ret, next_label); /* next */
     if(type == NODE_WHILE){
-      ADD_SEQ(ret, compile_branch_conditon(self, node->nd_cond,
-                                           redo_label, end_label));
+      ADD_SEQ(ret, compile_branch_condition(self, node->nd_cond,
+                                            redo_label, end_label));
     }
     else{
       /* untile */
-      ADD_SEQ(ret, compile_branch_conditon(self, node->nd_cond,
-                                           end_label, redo_label));
+      ADD_SEQ(ret, compile_branch_condition(self, node->nd_cond,
+                                            end_label, redo_label));
     }
 
     ADD_LABEL(ret, end_label);

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-06-08 03:03:49 UTC (rev 167)
+++ trunk/test.rb	2005-06-08 13:33:00 UTC (rev 168)
@@ -9,6 +9,23 @@
 ###########################################################
 $prog =<<'__EOP__'
 
+def f x, y, z
+  if (x and y) or z
+    1
+  else
+    2
+  end
+end
+
+
+__END__
+a = b = c = 0
+if a and b or c
+  p 'hoge'
+end
+
+
+__END__
 a = b = 0
 while a < 10 and b < 5
   a = b = a+1


--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]