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

yarv-diff:9

From: ko1 atdot.net
Date: 6 Jun 2005 06:41:58 -0000
Subject: [yarv-diff:9] r164 - in trunk: . test

Author: ko1
Date: 2005-06-06 15:41:57 +0900 (Mon, 06 Jun 2005)
New Revision: 164

Modified:
   trunk/ChangeLog
   trunk/compile.c
   trunk/compile.h
   trunk/test.rb
   trunk/test/test_syn.rb
   trunk/yarvcore.c
   trunk/yarvcore.h
Log:
	* yarvcore.h, yarvcore.c : add link structure to insn and label object

	* compile.h, compile.c : remove some variables in function top scope
	of iseq_compile_each and some optimization (now working)



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-06-04 07:12:37 UTC (rev 163)
+++ trunk/ChangeLog	2005-06-06 06:41:57 UTC (rev 164)
@@ -4,9 +4,16 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-06-06(Mon) 15:38:44 +0900  Koichi Sasada  <ko1 atdot.net>
 
-2005-06-04(Sat) 16:12:59 +0900
+	* yarvcore.h, yarvcore.c : add link structure to insn and label object
 
+	* compile.h, compile.c : remove some variables in function top scope
+	of iseq_compile_each and some optimization (now working)
+
+
+2005-06-04(Sat) 16:12:59 +0900  Koichi Sasada  <ko1 atdot.net>
+
 	* compile.c : fix previous commit
 
 

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2005-06-04 07:12:37 UTC (rev 163)
+++ trunk/compile.c	2005-06-06 06:41:57 UTC (rev 164)
@@ -181,8 +181,8 @@
 
 VALUE thread_eval_body(VALUE);
 
+static VALUE iseq_translate_direct_threaded_code(VALUE self){
 #ifdef DISPATCH_DIRECT_THREADED_CODE
-static VALUE iseq_translate_direct_threaded_code(VALUE self){
   struct iseq_object *iseqobj;
   void **table = (void **)thread_eval_body(0);
   int i, len;
@@ -197,16 +197,73 @@
     iseqobj->iseq_dt[i] = (VALUE)table[insn];
     i += len;
   }
+#endif
   return self;
 }
-#endif
 
+struct link_anchor{
+  struct iseq_link_element anchor;
+  struct iseq_link_element *last;
+};
 
+#define ADD_LINKED_LIST(anchor, obj) \
+{ \
+  (anchor)->last->next = (obj); \
+  (anchor)->last = (obj); \
+}
+
+#define APPEND_LINKED_LIST(list1, list2) \
+{ \
+  list1->last->next = list3->first.next; \
+  list1->last       = list2->last; \
+}
+
+#define FIRST_ELEMENT(list) ((list)->anchor.next)
+
+void iseq_array_to_linkedlist_each(struct link_anchor *anchor, VALUE aval){
+  struct RArray *ary = RARRAY(aval);
+  int i, len = ary->len;
+
+  for(i=0; i<len; i++){
+    VALUE obj = ary->ptr[i];
+    if(obj == Qnil){
+      /* ignore */
+    }
+    else if(BUILTIN_TYPE(obj) == T_ARRAY){
+      iseq_array_to_linkedlist_each(anchor, obj);
+    }
+    else if(BUILTIN_TYPE(obj) == T_DATA){
+      /* maybe Insn or Label */
+      struct iseq_link_element *le =
+        (struct iseq_link_element *)DATA_PTR(obj);
+      ADD_LINKED_LIST(anchor, le);
+    }
+  }
+}
+
+static struct iseq_link_element *iseq_array_to_linkedlist(VALUE self, VALUE seq_ary){
+  struct link_anchor anchor;
+  anchor.anchor.next = 0;
+  anchor.last        = &anchor.anchor;
+  
+  if(CLASS_OF(seq_ary) != rb_cArray){
+    rb_bug("error: iseq_array_to_linkedlist");
+  }
+  else{
+    iseq_array_to_linkedlist_each(&anchor, seq_ary);
+  }
+  return FIRST_ELEMENT(&anchor);
+}
+
 static VALUE iseq_setup(VALUE self, VALUE seq_ary, struct iseq_object *iseqobj){
+  struct iseq_link_element *seq_list;
   debugs("[compile step 2]\n");
+  // seq_list = iseq_array_to_linkedlist(self, seq_ary);
+
   /* must flatten! seq_ary */
   rb_funcall(seq_ary, rb_intern("flatten!"), 0);
 
+  
   GC_CHECK();
 
 #if CPDEBUG > 5
@@ -222,10 +279,6 @@
   debugs("[compile step 3.1.1 (iseq_insns_unification)]\n");
   seq_ary = iseq_insns_unification(self, seq_ary);
 
-  debugs("[compile step 3.2 (set_sequence_stackcaching)]\n");
-  seq_ary = set_sequence_stackcaching(seq_ary);
-  if(seq_ary == 0){ return 0; }
-
   debugs("[compile step 4 (set_sequence)]\n");
   set_sequence(self, seq_ary);
 
@@ -248,10 +301,7 @@
   iseq_disasm(self);
 #endif
   
-#ifdef DISPATCH_DIRECT_THREADED_CODE
   iseq_translate_direct_threaded_code(self);
-#endif
-  
   return self;
 }
 
@@ -538,7 +588,94 @@
   return self;
 }
 
+static int next_instruction_position(VALUE self, struct RArray *ary, int pos){
+  int i;
+  for(i=pos+1; i<ary->len; i++){
+    if(CLASS_OF(ary->ptr[i]) == cYarvInsn){
+      return i;
+    }
+  }
+  return -1;
+}
+
 /**
+
+ */
+void optimize_serial(VALUE self, VALUE seq){
+#if 0
+  struct RArray *ary = RARRAY(seq);
+  int i, len = ary->len;
+  VALUE obj;
+  struct insn_object *iobj;
+  
+  for(i=0; i<len; i++){
+    obj = ary->ptr[i];
+    if(obj == Qnil){
+      /* ignore */
+    }
+    else if(CLASS_OF(obj) == cYarvInsn){
+      GetInsnVal(obj, iobj);
+      if(iobj->insn_id == BIN(jump)){
+        VALUE lv = OPERAND_OF_RAW(iobj, 0);
+        struct label_object *lobj;
+        int vpos, j, jump_next_pos, label_next_pos;
+        GetLabelVal(lv, lobj);
+        vpos = lobj->vposition;
+
+        /*
+         * unused jump elimination
+         *
+         * case 1: jump to next insn
+         *
+         *     jump LABEL
+         *   LABEL:
+         *
+         *   => this jump instruction should be elimination
+         *
+         *
+         * case 2: jump to jump insn
+         *
+         *     jump LABEL1
+         *     ...
+         *   LABEL2:
+         *     jump LABEL2
+         *
+         *   => in this case, first jump instruction should jump tp
+         *      LABEL2 directly
+         
+         */
+        j = i;
+      check_jump:
+        jump_next_pos  = next_instruction_position(self, ary, j);
+        label_next_pos = next_instruction_position(self, ary, vpos);
+        
+        
+        /* check case 1 */
+        if(jump_next_pos == label_next_pos){
+          ary->ptr[j] = Qnil;
+        }
+        else{
+          /* check case 2 */
+          if(INSN_OF(ary->ptr[label_next_pos]) == BIN(jump)){
+            OPERAND(ary->ptr[j], 0) = OPERAND(ary->ptr[label_next_pos], 0);
+          }
+        }
+      }
+    }
+  }
+  /*
+    else if(CLASS_OF(obj) == cYarvLabel){
+    //
+    }
+    else{
+      rb_bug("optimize_serial error");
+    }
+  }
+   */
+#endif
+}
+
+/**
   ruby insn object array -> raw instruction sequence
  */
 VALUE set_sequence(VALUE self, VALUE seq){
@@ -580,8 +717,13 @@
       return 0;
     }
   }
+
+  optimize_serial(self, seq);
+  debugs("[compile step 3.2 (set_sequence_stackcaching)]\n");
+  seq = set_sequence_stackcaching(seq);
+  ary = RARRAY(seq);
   
-  // make instruction sequence
+  /* make instruction sequence */
   iseq = ALLOC_N(VALUE, pos);
   insn_info_tbl = ALLOC_N(struct insn_info_struct, k);
 
@@ -772,7 +914,7 @@
   return seq_ary;
 }
 
-VALUE iseq_insns_unification(VALUE self, VALUE seq_ary){
+static VALUE iseq_insns_unification(VALUE self, VALUE seq_ary){
 #ifdef OPT_INSNS_UNIFICATION
   return insns_unification(self, seq_ary);
 #else
@@ -991,6 +1133,29 @@
   return iseqobj->local_size;
 }
 
+static VALUE compile_branch_conditon(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);
+    break;
+
+  case NODE_AND:
+    
+  case NODE_OR:
+    break;
+
+  default:
+    ADD_SEQ  (ret, COMPILE("branch condition", cond));
+    ADD_INSNL(ret, nd_line(cond), unless, else_label);
+    ADD_INSNL(ret, nd_line(cond), jump,   then_label);
+    break;
+  }
+  return ret;
+}
+
 static VALUE compile_array(VALUE self, NODE *node_root, VALUE opt_p){
   NODE *node = node_root;
   VALUE obj, tmp, ret;
@@ -1190,15 +1355,11 @@
   poped: This node will be poped
  */
 static VALUE iseq_compile_each(VALUE self, NODE* node, int poped){
-  VALUE volatile tmp; /* reserved by macro */
-  VALUE volatile ret  = Qnil;
-  VALUE volatile iseq = Qnil;
-  VALUE volatile l1, l2;
-  VALUE volatile head;
-  VALUE volatile next;
-  VALUE volatile obj;
-  NODE  volatile *n = node;
+  VALUE tmp; /* reserved for macro */
+  VALUE ret  = Qnil;
+  NODE *n = node;
   VALUE args[10];
+  
   int lv, type;
   struct iseq_object *iseqobj;
 
@@ -1254,30 +1415,36 @@
     break;
   }
   case NODE_IF:{
-    volatile VALUE cond;
-    volatile VALUE thn;
-    volatile VALUE els;
+    VALUE cond_seq;
+    VALUE then_seq;
+    VALUE else_seq;
+    VALUE then_label, else_label, end_label;
 
-    cond = COMPILE("cond", node->nd_cond);
-    thn  = COMPILE_("then", node->nd_body, poped);
-    els  = COMPILE_("else", node->nd_else, poped);
-    
-    l1   = NEW_LABEL(nd_line(node));
-    l2   = NEW_LABEL(nd_line(node));
     ret  = NEW_SEQ  ();
 
-    debugp_verbose("cond", cond);
-    debugp_verbose("then", thn);
-    debugp_verbose("else", els);
+    then_label = NEW_LABEL(nd_line(node));
+    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);
+    then_seq = COMPILE_("then", node->nd_body, poped);
+    else_seq = COMPILE_("else", node->nd_else, poped);
+
+    debugp_verbose("cond", cond_seq);
+    debugp_verbose("then", then_seq);
+    debugp_verbose("else", else_seq);
+
+    ADD_SEQ  (ret, cond_seq);
     
-    ADD_SEQ  (ret, cond);
-    ADD_INSNL(ret, nd_line(node), unless, l1);
-    ADD_SEQ  (ret, thn);
-    ADD_INSNL(ret, nd_line(node), jump,   l2);
-    ADD_LABEL(ret, l1);
-    ADD_SEQ  (ret, els);
-    ADD_LABEL(ret, l2);
+    ADD_LABEL(ret, then_label);
+    ADD_SEQ  (ret, then_seq);
+    ADD_INSNL(ret, nd_line(node), jump,   end_label);
     
+    ADD_LABEL(ret, else_label);
+    ADD_SEQ  (ret, else_seq);
+    
+    ADD_LABEL(ret, end_label);
+    
     break;
   }
   case NODE_CASE:{
@@ -1305,6 +1472,8 @@
     ADD_SEQ (ret, head); /* case VAL */
     
     while(type == NODE_WHEN){
+      VALUE l1;
+      
       l1  = NEW_LABEL(nd_line(node));
       ADD_LABEL(body_seq, l1);
       ADD_INSN (body_seq, nd_line(node), pop);
@@ -1381,7 +1550,7 @@
     endlabel = NEW_LABEL(nd_line(node));
 
     while(nd_type(node) == NODE_WHEN){
-      l1  = NEW_LABEL(nd_line(node));
+      VALUE l1  = NEW_LABEL(nd_line(node));
       ADD_LABEL(body_seq, l1);
       ADD_SEQ  (body_seq, COMPILE_("when", node->nd_body, poped));
       ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
@@ -1630,7 +1799,7 @@
     
   case NODE_AND:
   case NODE_OR:{
-    l1 = NEW_LABEL(nd_line(node));
+    VALUE end_label = NEW_LABEL(nd_line(node));
     ret = NEW_SEQ();
     ADD_SEQ  (ret, COMPILE("nd_1st", node->nd_1st));
     if(!poped){
@@ -1638,14 +1807,14 @@
     }
     
     if(type == NODE_AND){
-      ADD_INSNL(ret, nd_line(node), unless, l1);
+      ADD_INSNL(ret, nd_line(node), unless, end_label);
     }
     else{
-      ADD_INSNL(ret, nd_line(node), if, l1);
+      ADD_INSNL(ret, nd_line(node), if, end_label);
     }
     ADD_INSN (ret, nd_line(node), pop);
     ADD_SEQ  (ret, COMPILE_("nd_2nd", node->nd_2nd, poped));
-    ADD_LABEL(ret, l1);
+    ADD_LABEL(ret, end_label);
     
     break;
   }
@@ -1770,6 +1939,8 @@
   }
   case NODE_LASGN:{
     int idx = get_root_iseq_localsize(iseqobj) + 2 - node->nd_cnt;
+    VALUE obj;
+    
     debugs("lvar: %d\n", idx);
     obj = COMPILE("lvalue", node->nd_value);
     ret = NEW_SEQ();
@@ -2634,9 +2805,9 @@
     break;
   }
   case NODE_DEFN:{
-    iseq = NEW_ISEQOBJ(node->nd_defn,
-                       rb_str_new2(rb_id2name(node->nd_mid)),
-                       ISEQ_TYPE_METHOD);
+    VALUE iseq = NEW_ISEQOBJ(node->nd_defn,
+                             rb_str_new2(rb_id2name(node->nd_mid)),
+                             ISEQ_TYPE_METHOD);
     
     debugp_param("defn/iseq", iseq);
 
@@ -2649,9 +2820,9 @@
     break;
   }
   case NODE_DEFS:{
-    iseq = NEW_ISEQOBJ(node->nd_defn,
-                       rb_str_new2(rb_id2name(node->nd_mid)),
-                       ISEQ_TYPE_METHOD);
+    VALUE iseq = NEW_ISEQOBJ(node->nd_defn,
+                             rb_str_new2(rb_id2name(node->nd_mid)),
+                             ISEQ_TYPE_METHOD);
 
     debugp_param("defs/iseq", iseq);
 
@@ -2700,8 +2871,8 @@
     break;
   }
   case NODE_CLASS:{
-    iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("class"),
-                       ISEQ_TYPE_CLASS);
+    VALUE iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("class"),
+                             ISEQ_TYPE_CLASS);
     
     ret = NEW_SEQ();
     ADD_SEQ  (ret, COMPILE("cbase", node->nd_cpath->nd_head));
@@ -2715,8 +2886,8 @@
     break;
   }
   case NODE_MODULE:{
-    iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("module"),
-                       ISEQ_TYPE_CLASS);
+    VALUE iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("module"),
+                             ISEQ_TYPE_CLASS);
     ret = NEW_SEQ();
     ADD_SEQ  (ret, COMPILE("mbase", node->nd_cpath->nd_head));
     ADD_INSN2(ret, nd_line(node), moduledef, ID2SYM(node->nd_cpath->nd_mid), iseq);
@@ -2727,9 +2898,10 @@
     break;
   }
   case NODE_SCLASS:{
+    VALUE iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("singletonclass"),
+                             ISEQ_TYPE_CLASS);
+
     ret = NEW_SEQ();
-    iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("singletonclass"),
-                       ISEQ_TYPE_CLASS);
     ADD_SEQ  (ret, COMPILE("sclass#recv", node->nd_recv));
     ADD_INSN1(ret, nd_line(node), singletonclassdef, iseq);
     if(poped){

Modified: trunk/compile.h
===================================================================
--- trunk/compile.h	2005-06-04 07:12:37 UTC (rev 163)
+++ trunk/compile.h	2005-06-06 06:41:57 UTC (rev 164)
@@ -190,9 +190,15 @@
   (debugs("== " desc "\n"),          \
    iseq_compile_each(self, node, poped))
 
+#define INSN_CODE(insn_obj) \
+  (((struct insn_object*)DATA_PTR(insn_obj))->insn_code)
+
 #define OPERAND(insn_obj, i) \
   (RARRAY(((struct insn_object*)DATA_PTR(insn_obj))->operands)->ptr[i])
 
+#define OPERAND_OF_RAW(insn_obj, i) \
+  (RARRAY(insn_obj->operands)->ptr[i])
+
 #define INSN_OF(insn) \
   (((struct insn_object*)DATA_PTR(insn))->insn_id)
      
@@ -201,7 +207,6 @@
 static VALUE new_insn(int insn, int line_no, VALUE operands);
 
 
-
 /* error */
 #define COMPILE_ERROR(strs)                        \
 {                                                  \
@@ -215,5 +220,6 @@
   break;                                           \
 }
 
+
 #endif	// _COMPILER_H_INCLUDED_
 

Modified: trunk/test/test_syn.rb
===================================================================
--- trunk/test/test_syn.rb	2005-06-04 07:12:37 UTC (rev 163)
+++ trunk/test/test_syn.rb	2005-06-06 06:41:57 UTC (rev 164)
@@ -62,6 +62,9 @@
     ae %q(1 and nil and 3 and 4)
     ae %q(1 and 2 and 3 and nil)
     ae %q(1 and 2 and 3 and false)
+    ae %q(nil && true)
+    ae %q(false && true)
+
   end
   
   def test_or

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-06-04 07:12:37 UTC (rev 163)
+++ trunk/test.rb	2005-06-06 06:41:57 UTC (rev 164)
@@ -8,6 +8,37 @@
 $line = __LINE__ + 3
 ###########################################################
 $prog =<<'__EOP__'
+
+if true
+
+end
+__END__
+
+a = true
+
+a = 1 + if !a
+          2
+        else
+          3
+        end + 4
+
+p a
+p '---------'
+__END__
+p((nil and true) == (false and true))
+__END__
+a = false
+b = true
+
+if a and b
+  p :then
+else
+  p :else
+end
+
+
+__END__
+
 class C
   attr_accessor :a
 end

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2005-06-04 07:12:37 UTC (rev 163)
+++ trunk/yarvcore.c	2005-06-06 06:41:57 UTC (rev 164)
@@ -409,6 +409,8 @@
 static VALUE label_init(VALUE self, VALUE label_no){
   struct label_object *labelobj;
   Data_Get_Struct(self, struct label_object, labelobj);
+  labelobj->link.type = ISEQ_ELEMENT_LABEL;
+  labelobj->link.next = 0;
   labelobj->label_no = label_no;
   labelobj->sc_state = 0;
   return self;
@@ -450,12 +452,14 @@
   struct insn_object *insnobj;
 
   obj = Data_Make_Struct(klass, struct insn_object, insn_mark, yarv_free, insnobj);
-  return obj;
+    return obj;
 }
 
 static VALUE insn_init(VALUE self, int insn_id, int line_no, VALUE operands){
   struct insn_object *insnobj;
   Data_Get_Struct(self, struct insn_object, insnobj);
+  insnobj->link.type = ISEQ_ELEMENT_INSN;
+  insnobj->link.next = 0;
   insnobj->insn_id  = insn_id;
   insnobj->line_no  = line_no;
   insnobj->operands = operands; /* 0 or RArray */

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-06-04 07:12:37 UTC (rev 163)
+++ trunk/yarvcore.h	2005-06-06 06:41:57 UTC (rev 164)
@@ -49,7 +49,19 @@
 #define GetLabelVal(obj, lobj) \
   Data_Get_Struct(obj, struct label_object, lobj)
 
+
+#define ISEQ_ELEMENT_NONE  INT2FIX(0x00)
+#define ISEQ_ELEMENT_LABEL INT2FIX(0x01)
+#define ISEQ_ELEMENT_INSN  INT2FIX(0x02)
+#define ISEQ_ELEMENT_SEQ   INT2FIX(0x03)
+
+struct iseq_link_element{
+  int type;
+  struct iseq_link_element *next;
+};
+
 struct label_object{
+  struct iseq_link_element link;
   int label_no;
   long position;
   unsigned long sc_state;
@@ -61,6 +73,7 @@
   Data_Get_Struct(obj, struct insn_object, iobj)
 
 struct insn_object{
+  struct iseq_link_element link;
   int insn_id;
   unsigned long line_no;
   VALUE operands;


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

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