yarv-diff:4
From: ko1 atdot.net
Date: 3 Jun 2005 18:43:03 -0000
Subject: [yarv-diff:4] r159 - in trunk: . benchmark
Author: ko1
Date: 2005-06-04 03:43:02 +0900 (Sat, 04 Jun 2005)
New Revision: 159
Modified:
trunk/ChangeLog
trunk/benchmark/bmx_temp.rb
trunk/compile.c
trunk/test.rb
trunk/yarvcore.c
trunk/yarvcore.h
Log:
* yarvcore.h, yarvcore.c : add some temporary variable test
(it'll be vanished)
* compile.c : NODE_CASE optimize (use topn instead of dup/swap)
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-06-02 16:01:10 UTC (rev 158)
+++ trunk/ChangeLog 2005-06-03 18:43:02 UTC (rev 159)
@@ -4,6 +4,14 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-06-04(Sat) 03:41:29 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * yarvcore.h, yarvcore.c : add some temporary variable test
+ (it'll be vanished)
+
+ * compile.c : NODE_CASE optimize (use topn instead of dup/swap)
+
+
2005-06-03(Fri) 00:54:38 +0900 Koichi Sasada <ko1 atdot.net>
* compile.c : apply flow optimization for while/until statement
Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb 2005-06-02 16:01:10 UTC (rev 158)
+++ trunk/benchmark/bmx_temp.rb 2005-06-03 18:43:02 UTC (rev 159)
@@ -1,8 +1,10 @@
i=0
-f=0.0
-while i<50000000
-# f = 'a'+'b'
-# f = f + 2.2
+while i<500000
i+=1
+ case :a
+ when :x
+ when :y
+ when :z
+ end
end
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-06-02 16:01:10 UTC (rev 158)
+++ trunk/compile.c 2005-06-03 18:43:02 UTC (rev 159)
@@ -525,7 +525,7 @@
GetISeqVal(self, iseqobj);
if(tbl){
- size = *tbl - 2 + 1;
+ size = *tbl - 2 /* $~, $_ */ + 1 /* svar location */;
}
else{
size = 1;
@@ -947,22 +947,97 @@
return ret;
}
-
-static int get_root_iseq_localsize(struct iseq_object *iop){
+static struct iseq_object *get_root_iseq_object(struct iseq_object *iop){
struct iseq_object *iseqobj = iop;
while(iseqobj){
if(iseqobj->parent_iseqobj){
iseqobj = iseqobj->parent_iseqobj;
}
else{
- return iseqobj->local_size;
+ return iseqobj;
}
}
- rb_bug("get_root_iseq_localsize error");
- return -1;
+ /* unreachable */
+ rb_bug("get_root_iseq_object error");
+ return 0;
}
+static int get_root_iseq_localsize(struct iseq_object *iseqobj){
+ iseqobj = get_root_iseq_object(iseqobj);
+ return iseqobj->local_size;
+}
+static int get_temporary_variable_index(struct iseq_object *iseqobj){
+ int idx;
+ VALUE tvarary;
+
+ tvarary = iseqobj->compile_data->temporary_variables;
+ if(tvarary == 0){
+ tvarary = iseqobj->compile_data->temporary_variables = rb_ary_new();
+ }
+
+ if(RARRAY(tvarary)->len == 0){
+ int num = iseqobj->compile_data->temporary_variables_num ++;
+ char tvarstr[0x10];
+ int old_size = iseqobj->local_size;
+ ID *old_tbl = iseqobj->local_tbl;
+
+ /* new symbol name */
+ snprintf(tvarstr, 0x10, "_$%d", num);
+
+ /* add new symbol to local table */
+ iseqobj->local_tbl = (ID*)ALLOC_N(ID*, old_size + 1);
+ iseqobj->local_size += 1;
+ MEMCPY(iseqobj->local_tbl, old_tbl, ID*, old_size);
+ ruby_xfree(old_tbl);
+ iseqobj->local_tbl[old_size] = rb_intern(tvarstr);
+ idx = old_size;
+ }
+ else{
+ idx = FIX2INT(rb_ary_pop(tvarary));
+ }
+
+ return idx;
+}
+
+static void release_temporary_variable_index(struct iseq_object *iseqobj, int idx){
+ if(iseqobj->compile_data->temporary_variables){
+ rb_ary_push(iseqobj->compile_data->temporary_variables, INT2FIX(idx));
+ }
+ else{
+ rb_bug("release_temporary_local_variable error");
+ }
+}
+
+static void get_temporary_variable_set_insn(struct iseq_object *iseqobj,
+ VALUE seq, int line, int idx){
+ int ls = iseqobj->local_size;
+
+ if(iseqobj->parent_iseqobj){
+ /* dvar */
+ ADD_INSN2(seq, line, setdynamic, I2F(ls - idx), I2F(0));
+ }
+ else{
+ /* lvar */
+ ADD_INSN1(seq, line, setlocal, I2F(ls - idx - 2 /* block + svar */));
+ }
+}
+
+static void set_temporary_variable_get_insn(struct iseq_object *iseqobj,
+ VALUE seq, int line, int idx){
+ int ls = iseqobj->local_size;
+
+ if(iseqobj->parent_iseqobj){
+ /* dvar */
+ ADD_INSN2(seq, line, getdynamic, I2F(ls - idx), I2F(0));
+ }
+ else{
+ /* lvar */
+ ADD_INSN1(seq, line, getlocal, I2F(ls - idx - 2 /* block + svar */));
+ }
+}
+
+
static VALUE compile_array(VALUE self, NODE *node_root, VALUE opt_p){
NODE *node = node_root;
VALUE obj, tmp, ret;
@@ -1239,16 +1314,16 @@
break;
}
case NODE_CASE:{
- volatile VALUE head = COMPILE("case base", node->nd_head);
+ VALUE head = COMPILE("case base", node->nd_head);
NODE* vals;
NODE* val;
NODE* tempnode = node;
- volatile VALUE endlabel;
- volatile VALUE body_seq;
-
+ VALUE endlabel;
+ VALUE body_seq;
+
node = node->nd_body;
type = nd_type(node);
-
+
if(type != NODE_WHEN){
COMPILE_ERROR(("NODE_CASE: unexpected node. must be NODE_WHEN, byt %s", node_name(type)));
}
@@ -1256,8 +1331,9 @@
ret = NEW_SEQ();
body_seq = NEW_SEQ();
endlabel = NEW_LABEL(nd_line(node));
- ADD_SEQ (ret, head);
+ ADD_SEQ (ret, head); /* case VAL */
+
while(type == NODE_WHEN){
l1 = NEW_LABEL(nd_line(node));
ADD_LABEL(body_seq, l1);
@@ -1278,9 +1354,8 @@
| cond_val(self)
| obj(dupped)
*/
- ADD_INSN (ret, nd_line(node), dup);
- ADD_SEQ (ret, COMPILE("when cond", val));
- ADD_INSN (ret, nd_line(node), swap);
+ ADD_SEQ (ret, COMPILE("when cond", val));
+ ADD_INSN1(ret, nd_line(node), topn, INT2FIX(1));
ADD_SEND (ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
ADD_INSNL(ret, nd_line(node), if, l1);
vals = vals->nd_next;
@@ -1289,6 +1364,7 @@
else{
COMPILE_ERROR(("NODE_CASAE: must be NODE_ARRAY, but %s\n", node_name(nd_type(vals))));
}
+
node = node->nd_next;
if(!node){
break;
@@ -1412,7 +1488,7 @@
rb_str_concat(name, iseqobj->name);
iseqobj->compile_data->current_block = NEW_CHILD_ISEQOBJ(node, name,
- self, ISEQ_TYPE_BLOCK);
+ self, ISEQ_TYPE_BLOCK);
ret = NEW_SEQ();
ADD_LABEL(ret, retry_label);
ADD_SEQ (ret, COMPILE_("iter caller", node->nd_iter, poped));
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-06-02 16:01:10 UTC (rev 158)
+++ trunk/test.rb 2005-06-03 18:43:02 UTC (rev 159)
@@ -9,6 +9,36 @@
###########################################################
$prog =<<'__EOP__'
+i=0
+while i<500000
+ i+=1
+ case :a
+ when :x
+ when :y
+ when :z
+ end
+end
+
+__END__
+a = b = c = :b
+
+case a
+when :a
+ p :a
+when :b
+ p :b
+else
+ p :else
+end
+
+case a
+when :a
+ p :a
+when :b
+ p :b
+end
+
+__END__
i = 0
while i<3
i+=1
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-06-02 16:01:10 UTC (rev 158)
+++ trunk/yarvcore.c 2005-06-03 18:43:02 UTC (rev 159)
@@ -316,7 +316,7 @@
MARK_UNLESS_NULL(iseqobj->compile_data->end_label);
MARK_UNLESS_NULL(iseqobj->compile_data->redo_label);
MARK_UNLESS_NULL(iseqobj->compile_data->err_info);
- MARK_UNLESS_NULL(iseqobj->compile_data->compile_data);
+ MARK_UNLESS_NULL(iseqobj->compile_data->temporary_variables);
}
}
}
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2005-06-02 16:01:10 UTC (rev 158)
+++ trunk/yarvcore.h 2005-06-03 18:43:02 UTC (rev 159)
@@ -96,20 +96,19 @@
};
struct iseq_compile_data{
+ /* GC is needed */
VALUE current_block;
-
VALUE start_label;
VALUE end_label;
VALUE redo_label;
-
+ VALUE err_info;
+ VALUE temporary_variables;
+
+ /* GC is not needed */
VALUE loopval_popped; /* used by NODE_BREAK */
VALUE in_ensure; /* used by NODE_RETURN */
-
- VALUE err_info;
-
int cached_const;
-
- VALUE compile_data;
+ int temporary_variables_num;
};
struct iseq_object{
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml