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