yarv-diff:17
From: ko1 atdot.net
Date: 26 Jun 2005 05:13:29 -0000
Subject: [yarv-diff:17] r172 - in trunk: . benchmark rb
Author: ko1
Date: 2005-06-26 14:13:28 +0900 (Sun, 26 Jun 2005)
New Revision: 172
Modified:
trunk/ChangeLog
trunk/benchmark/bm_factorial.rb
trunk/benchmark/bmx_temp.rb
trunk/benchmark/run.rb
trunk/compile.c
trunk/compile.h
trunk/insns.def
trunk/opt_insn_unif.def
trunk/opt_operand.def
trunk/rb/insns2vm.rb
trunk/test.rb
trunk/vm.c
Log:
* benchmark/run.rb : use tmpfile instead of popen
* rb/insns2vm.rb : fix generating insn unification logic
* opt_insn_unif.def : add some unification rules
* compile.c : add verify_list function and fix unification logic
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/ChangeLog 2005-06-26 05:13:28 UTC (rev 172)
@@ -4,6 +4,17 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-06-26(Sun) 14:06:22 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * benchmark/run.rb : use tmpfile instead of popen
+
+ * rb/insns2vm.rb : fix generating insn unification logic
+
+ * opt_insn_unif.def : add some unification rules
+
+ * compile.c : add verify_list function and fix unification logic
+
+
2005-06-22(Wed) 12:58:26 +0900 Koichi Sasada <ko1 atdot.net>
* yarvcore.h, yarvcore.c, insns.def, compile.c : add mult optimization
Modified: trunk/benchmark/bm_factorial.rb
===================================================================
--- trunk/benchmark/bm_factorial.rb 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/benchmark/bm_factorial.rb 2005-06-26 05:13:28 UTC (rev 172)
@@ -6,4 +6,6 @@
end
end
-fact(7300)
+30.times{
+ fact(7300)
+}
\ No newline at end of file
Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/benchmark/bmx_temp.rb 2005-06-26 05:13:28 UTC (rev 172)
@@ -1,7 +1,8 @@
+def m
+end
+
i=0
-a = b = true
-while i<10000000
- if a and b
- end
-i+=1
+while i<1000000
+ i+=1
+ m; m; m; m; m; m; m; m; m; m
end
Modified: trunk/benchmark/run.rb
===================================================================
--- trunk/benchmark/run.rb 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/benchmark/run.rb 2005-06-26 05:13:28 UTC (rev 172)
@@ -63,16 +63,18 @@
EOP
end
-def benchmark cmd
+def benchmark prog
rubybin = ENV['RUBY'] || File.join(
Config::CONFIG["bindir"],
Config::CONFIG["ruby_install_name"] + Config::CONFIG["EXEEXT"])
-
- IO.popen(rubybin, 'r+'){|io|
- io.write cmd
- io.close_write
- puts io.gets
- }
+
+ #
+ tmpfile = Tempfile.new('yarvbench')
+ tmpfile.write(prog)
+ tmpfile.close
+ cmd = "#{rubybin} #{tmpfile.path}"
+ puts `#{cmd}`
+ tmpfile.close(true)
end
def ruby_exec file
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/compile.c 2005-06-26 05:13:28 UTC (rev 172)
@@ -265,6 +265,29 @@
* To make Array to LinkedList, use link_anchor
*/
+
+static void verify_list(char *info, ISEQ_LINK_ANCHOR *anchor){
+#if CPDEBUG > 0
+ int flag = 0;
+ ISEQ_LINK_ELEMENT* list = anchor->anchor.next,
+ * plist= &anchor->anchor;
+ while(list){
+ if(plist != list->prev){
+ flag += 1;
+ }
+ plist = list;
+ list = list->next;
+ }
+ if(anchor->last != plist){
+ flag |= 0x70000;
+ }
+
+ if(flag != 0){
+ rb_bug("list verify error: %08x (%s)", flag, info);
+ }
+#endif
+}
+
/*
* elem1, elem2 => elem1, elem2, elem
*/
@@ -272,6 +295,7 @@
elem->prev = anchor->last;
anchor->last->next = elem;
anchor->last = elem;
+ verify_list("add", anchor);
}
/*
@@ -334,6 +358,7 @@
ISEQ_LINK_ELEMENT *elem = anchor->last;
anchor->last = anchor->last->prev;
anchor->last->next = 0;
+ verify_list("pop", anchor);
return elem;
}
@@ -352,13 +377,15 @@
* anc2: e4, e5
*#=>
* anc1: e1, e2, e3, e4, e5
- * anc2: e4, e5
+ * anc2: e4, e5 (broken)
*/
static void APPEND_LIST(ISEQ_LINK_ANCHOR *anc1, ISEQ_LINK_ANCHOR *anc2){
if(anc2->anchor.next){
anc1->last->next = anc2->anchor.next;
+ anc2->anchor.next->prev = anc1->last;
anc1->last = anc2->last;
}
+ verify_list("append", anc1);
}
static ISEQ_LINK_ANCHOR *REVERSE_LIST(ISEQ_LINK_ANCHOR *anc){
@@ -386,15 +413,14 @@
last->prev = first;
anc->last->next = 0;
+ verify_list("reverse", anc);
return anc;
}
-
static void debug_list(ISEQ_LINK_ANCHOR *anchor){
-#if CPDEBUG > 5
+#if CPDEBUG > 0
ISEQ_LINK_ELEMENT* list = FIRST_ELEMENT(anchor);
int i = 0;
-
printf("----\n");
printf("anch: %p, frst: %p, last: %p\n", &anchor->anchor, anchor->anchor.next, anchor->last);
while(list){
@@ -404,6 +430,7 @@
printf("----\n");
iseq_disasm_list_dump(anchor->anchor.next);
+ verify_list("debug list", anchor);
#endif
}
@@ -1192,6 +1219,7 @@
int i, argc = 0;
VALUE *operands = 0, *ptr = 0;
+
/* count argc */
for(i=0; i<size; i++){
iobj = (struct insn_object*)list;
@@ -1246,19 +1274,21 @@
}
/* matched */
niobj = new_unified_insn(iseqobj, unified[0], unified[1]-1, list);
-
+
/* insert to list */
niobj->link.prev = (ISEQ_LINK_ELEMENT *)iobj->link.prev;
niobj->link.next = li;
if(li){
li->prev = (ISEQ_LINK_ELEMENT *)niobj;
}
+
list->prev->next = (ISEQ_LINK_ELEMENT *)niobj;
list = (ISEQ_LINK_ELEMENT *)niobj;
- }
+ break;
+ miss:;
+ }
}
}
- miss:
list = list->next;
}
#endif
@@ -3225,9 +3255,13 @@
case NODE_DOT2:
case NODE_DOT3:{
int flag = type == NODE_DOT2 ? INT2FIX(0) : INT2FIX(1);
- if(!poped){
- COMPILE(ret, "min", (NODE*)node->nd_lit);
- COMPILE(ret, "max", (NODE*)node->nd_end);
+ COMPILE(ret, "min", (NODE*)node->nd_beg);
+ COMPILE(ret, "max", (NODE*)node->nd_end);
+ if(poped){
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ else{
ADD_INSN1(ret, nd_line(node), newrange, flag);
}
break;
Modified: trunk/compile.h
===================================================================
--- trunk/compile.h 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/compile.h 2005-06-26 05:13:28 UTC (rev 172)
@@ -28,7 +28,7 @@
#if 0
#undef CPDEBUG
-#define CPDEBUG 6
+#define CPDEBUG 1
#endif
#if CPDEBUG > 0
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/insns.def 2005-06-26 05:13:28 UTC (rev 172)
@@ -2136,4 +2136,3 @@
rb_bug("opt_call_native_compiled is not supported");
#endif
}
-
Modified: trunk/opt_insn_unif.def
===================================================================
--- trunk/opt_insn_unif.def 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/opt_insn_unif.def 2005-06-26 05:13:28 UTC (rev 172)
@@ -4,7 +4,14 @@
#
putobject putobject
+putobject putstring
+putobject setlocal
+putobject setdynamic
+
putstring putstring
putstring putobject
-putobject putstring
+putstring setlocal
+putstring setdynamic
+dup setlocal
+
Modified: trunk/opt_operand.def
===================================================================
--- trunk/opt_operand.def 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/opt_operand.def 2005-06-26 05:13:28 UTC (rev 172)
@@ -6,7 +6,7 @@
#
# wildcard: *
#
-# __END__
+
getlocal 1
setlocal 1
getlocal 2
Modified: trunk/rb/insns2vm.rb
===================================================================
--- trunk/rb/insns2vm.rb 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/rb/insns2vm.rb 2005-06-26 05:13:28 UTC (rev 172)
@@ -2,6 +2,7 @@
#
#
#
+# $verbose = true
require 'pp'
require 'erb'
@@ -9,7 +10,7 @@
class InsnsDef
class InsnInfo
- def initialize name, opes, pops, rets, comm, body,
+ def initialize name, opes, pops, rets, comm, body, tvars,
orig = self, defopes = [], type = nil,
nsc = [], psc = [[], []]
@@ -20,14 +21,16 @@
@comm = comm # {:c => category, :e => en desc, :j => ja desc}
@body = body # '...'
- @orig = orig
+ @orig = orig
@defopes = defopes
- @type = type
+ @type = type
+ @tvars = tvars
@nextsc = nsc
@pushsc = psc
@sc = []
@unifs = []
+ @optimized = []
@is_sc = false
end
@@ -41,8 +44,9 @@
attr_reader :nextsc, :pushsc
attr_reader :orig, :defopes, :type
attr_reader :sc
- attr_reader :unifs
+ attr_reader :unifs, :optimized
attr_reader :is_sc
+ attr_reader :tvars
def set_sc
@is_sc = true
@@ -52,6 +56,10 @@
@unifs << insns
end
+ def add_optimized insn
+ @optimized << insn
+ end
+
def inspect
"#<InsnInfo:#{@name}>"
end
@@ -85,7 +93,7 @@
end
def make_insn name, opes, pops, rets, comm, body
- add_insn InsnInfo.new(name, opes, pops, rets, comm, body)
+ add_insn InsnInfo.new(name, opes, pops, rets, comm, body, [])
end
@@ -231,8 +239,10 @@
def make_insn_operand_optimiized orig_insn, name, opes, defopes
comm = orig_insn.comm.dup
comm[:c] = 'optimize'
- add_insn InsnInfo.new(name, opes, orig_insn.pops, orig_insn.rets, comm, orig_insn.body,
- orig_insn, defopes)
+ add_insn insn = InsnInfo.new(
+ name, opes, orig_insn.pops, orig_insn.rets, comm,
+ orig_insn.body, orig_insn.tvars, orig_insn, defopes)
+ orig_insn.add_optimized insn
end
@@ -249,8 +259,43 @@
}}
end
+ def all_combination sets
+ ret = sets.shift.map{|e| [e]}
+
+ sets.each{|set|
+ prev = ret
+ ret = []
+ prev.each{|ary|
+ set.each{|e|
+ eary = ary.dup
+ eary << e
+ ret << eary
+ }
+ }
+ }
+ ret
+ end
+
+ def make_unified_insns insns
+
+ if false || true # all optimized insn
+ insn_sets = insns.map{|insn|
+ [insn] + insn.optimized
+ }
+
+ all_combination(insn_sets).each{|insns_set|
+ make_unified_insn_each insns_set
+ }
+ else
+ make_unified_insn_each insns
+ end
+ end
+
def mk_private_val vals, i, redef
vals.dup.map{|v|
+ # v[0] : type
+ # v[1] : var name
+
v = v.dup
if v[0] != '...'
redef[v[1]] = 1
@@ -259,8 +304,24 @@
v
}
end
-
- def make_unified_insns insns
+
+ def mk_private_val2 vals, i, redef
+ vals.dup.map{|v|
+ # v[0][0] : type
+ # v[0][1] : var name
+ # v[1] : default val
+
+ pv = v.dup
+ v = pv[0] = pv[0].dup
+ if v[0] != '...'
+ redef[v[1]] = 1
+ v[1] = "#{v[1]}_#{i}"
+ end
+ pv
+ }
+ end
+
+ def make_unified_insn_each insns
names = []
opes = []
pops = []
@@ -272,22 +333,75 @@
}
body = ''
passed = []
+ tvars = []
+ defopes = []
insns.each_with_index{|insn, i|
names << insn.name
redef_vars = {}
- opes.concat mk_private_val(insn.opes, i, redef_vars)
- pops.concat mk_private_val(insn.pops, i, redef_vars)
- rets.concat mk_private_val(insn.rets, i, redef_vars)
+
+ e_opes = mk_private_val(insn.opes, i, redef_vars)
+ e_pops = mk_private_val(insn.pops, i, redef_vars)
+ e_rets = mk_private_val(insn.rets, i, redef_vars)
+ # ToDo: fix it
+ e_defs = mk_private_val2(insn.defopes, i, redef_vars)
+
+ passed_vars = []
+ while pvar = e_pops.pop
+ rvar = rets.pop
+
+ if rvar
+ raise "unsupported unif insn: #{insns.inspect}" if rvar[0] == '...'
+ passed_vars << [pvar, rvar]
+ tvars << rvar
+ else
+ e_pops.push pvar
+ break
+ end
+ end
+
+ opes.concat e_opes
+ pops.concat e_pops
+ rets.concat e_rets
+ defopes.concat e_defs
- body += redef_vars.keys.map{|v| "#define #{v} #{v}_#{i}"}.join("\n") +
- "\n" + insn.body +
- redef_vars.keys.map{|v| "#undef #{v}"}.join("\n") + "\n"
+ body += #
+ passed_vars.map{|rpvars|
+ pv = rpvars[0]
+ rv = rpvars[1]
+ "#define #{pv[1]} #{rv[1]}\n"
+ }.join("\n") +
+ "\n" +
+ redef_vars.keys.map{|v|
+ "#define #{v} #{v}_#{i}"
+ }.join("\n") +
+ "\n" +
+ insn.body +
+ passed_vars.map{|rpvars|
+ "#undef #{rpvars[0][1]}"
+ }.join("\n") +
+ "\n" +
+ redef_vars.keys.map{|v|
+ "#undef #{v}"
+ }.join("\n") +
+ "\n"
}
+ tvars_ary = []
+ tvars.each{|tvar|
+ unless opes.any?{|var|
+ var[1] == tvar[1]
+ } || defopes.any?{|pvar|
+ pvar[0][1] == tvar[1]
+ }
+ tvars_ary << tvar
+ end
+ }
add_insn insn = InsnInfo.new("UNIFIED_" + names.join('_'),
- opes, pops, rets.reverse, comm, body)
+ opes, pops, rets.reverse, comm, body,
+ tvars_ary)
+ insn.defopes.replace defopes
insns[0].add_unif [insn, insns]
end
@@ -335,8 +449,10 @@
comm = orig_insn.comm.dup
comm[:c] = 'optimize(sc)'
- scinsn = InsnInfo.new(name, opes, pops, rets, comm, orig_insn.body,
- orig_insn, orig_insn.defopes, :sc, nextsc, pushs)
+ scinsn = InsnInfo.new(
+ name, opes, pops, rets, comm,
+ orig_insn.body, orig_insn.tvars, orig_insn, orig_insn.defopes, :sc, nextsc, pushs)
+
add_insn scinsn
#
orig_insn.add_sc scinsn
@@ -365,7 +481,11 @@
end
def calc_stack insn, ofrom, oafter, opops, orets
- from = ofrom.dup; pops = opops.dup; rets = orets.dup
+ from = ofrom.dup
+ pops = opops.dup
+ rets = orets.dup
+ rest_scr = ofrom.dup
+
pushs_before = []
pushs= []
@@ -390,16 +510,26 @@
break if e[0] == '...'
pushed, r = add_stack_value from
rets[i] = rets[i].dup << r
- pushs << pushed if pushed
+ if pushed
+ if rest_scr.pop
+ pushs << pushed
+ end
+
+ if i - 2 >= 0
+ rets[i-2].pop
+ end
+ end
}
end
- if false # insn == 'swap'
+ if false #|| insn.name =~ /test3/
p ofrom
p pops
p rets
p pushs_before
p pushs
+ p from
+ exit
end
ret = ["#{insn.name}_SC_#{complement_name(ofrom)}_#{complement_name(from)}",
@@ -491,6 +621,14 @@
pops.reverse.join("\n") + "\n"
end
+ def make_header_temporary_vars insn
+ ret = []
+ insn.tvars.each{|var|
+ ret << " #{var[0]} #{var[1]};"
+ }
+ ret.join("\n") + "\n"
+ end
+
def make_header_stack_val insn
ret = []
@@ -521,23 +659,23 @@
def make_header insn
ret = "\nINSN_ENTRY(#{insn.name}){\n"
- ret += " /* prepare stack status */\n" if $verbatim
+ ret += " /* prepare stack status */\n" if $verbose
ret += make_header_prepare_stack insn
ret += "{\n"
- ret += " /* declare stack push val */\n" if $verbatim
+ ret += " /* declare stack push val */\n" if $verbose
ret += make_header_stack_val insn
- ret += " /* declare and initialize default opes */\n" if $verbatim
+ ret += " /* declare and initialize default opes */\n" if $verbose
ret += make_header_default_operands insn
- ret += " /* declare and get from iseq */\n" if $verbatim
+ ret += " /* declare and get from iseq */\n" if $verbose
ret += make_header_operands insn
- ret += " /* declare and pop from stack */\n" if $verbatim
+ ret += " /* declare and pop from stack */\n" if $verbose
ret += make_header_stack_pops insn
+ ret += " /* declare temporary vars */\n" if $verbose
+ ret += make_header_temporary_vars insn
- ret += " /* for debug */\n" if $verbatim
+ ret += " /* for debug */\n" if $verbose
ret += " DEBUG_ENTER_INSN(\"#{insn.name}\");\n"
- ret += " USAGE_ANALYSIS_INSN(BIN(#{insn.name}));\n"
-
- ret += " /* management */\n" if $verbatim
+ ret += " /* management */\n" if $verbose
ret += " ADD_PC(1+#{@opn});\n"
ret += " POPN(#{@popn});\n" if @popn > 0
ret += " #define CURRENT_INSN_#{insn.name} 1\n"
@@ -545,6 +683,8 @@
ret += " #define INSN_LABEL(lab) LABEL_#{insn.name}_##lab\n"
ret += " #define LABEL_IS_SC(lab) LABEL_##lab##_###{insn.sc.size == 0 ? 't' : 'f'}\n"
+
+ ret += " USAGE_ANALYSIS_INSN(BIN(#{insn.name}));\n"
insn.opes.each_with_index{|op, i|
ret += " USAGE_ANALYSIS_OPERAND(BIN(#{insn.name}), #{i}, #{op[1]});\n"
}
@@ -554,7 +694,7 @@
def make_footer insn
ret = ''
- ret = " /* push stack val */\n" if $verbatim
+ ret = " /* push stack val */\n" if $verbose
ret += make_footer_stack_val insn
# debug info
@@ -717,7 +857,7 @@
when /^\.\.\./
raise
else
- raise
+ raise "type: #{type}"
end
end
@@ -730,7 +870,8 @@
@insns.each{|insn|
next if insn.defopes.size == 0
next if insn.type == :sc
-
+ next if /^UNIFIED/ =~ insn.name.to_s
+
originsn = insn.orig
opt_insns_map[originsn] << insn
}
@@ -783,7 +924,9 @@
insns.each{|insn|
size = insn.unifs.size
if size > 0
- insn.unifs.each_with_index{|unif, i|
+ require 'pp'
+
+ insn.unifs.sort_by{|unif| -unif[1].size}.each_with_index{|unif, i|
uni_insn, uni_insns = *unif
uni_insns = uni_insns[1..-1]
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/test.rb 2005-06-26 05:13:28 UTC (rev 172)
@@ -8,7 +8,31 @@
$line = __LINE__ + 3
###########################################################
$prog =<<'__EOP__'
+i=0
+a = b = true
+while i<10
+ if a and b
+ end
+ i+=1
+end
+__END__
+if /a/ =~ 'a'
+end
+__END__
+def fact(n)
+ if(n > 1)
+ n * fact(n-1)
+ else
+ 1
+ end
+end
+50.times{
+ fact(7300)
+}
+
+__END__
+
def fact(n)
if(n > 1)
n * fact(n-1)
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-06-22 04:00:37 UTC (rev 171)
+++ trunk/vm.c 2005-06-26 05:13:28 UTC (rev 172)
@@ -1376,7 +1376,7 @@
#include "vm_evalbody.inc"
#if __GNUC__
-#define thread_eval_body thread_eval_body_copy
-#include "vm_evalbody.inc"
+// #define thread_eval_body thread_eval_body_copy
+// #include "vm_evalbody.inc"
#endif
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml