yarv-diff:18
From: ko1 atdot.net
Date: 27 Jun 2005 07:55:27 -0000
Subject: [yarv-diff:18] r173 - in trunk: . rb
Author: ko1
Date: 2005-06-27 16:55:26 +0900 (Mon, 27 Jun 2005)
New Revision: 173
Modified:
trunk/ChangeLog
trunk/compile.c
trunk/depend
trunk/extconf.rb
trunk/rb/aotcompile.rb
trunk/rb/insns2vm.rb
trunk/test.rb
Log:
* insns2vm.rb : fix generating unif insn
* compile.c : add useless pop/swap insn elimination with stack caching
* depend : remove compiled.o dependency
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-06-26 05:13:28 UTC (rev 172)
+++ trunk/ChangeLog 2005-06-27 07:55:26 UTC (rev 173)
@@ -4,6 +4,15 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-06-27(Mon) 16:50:31 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * insns2vm.rb : fix generating unif insn
+
+ * compile.c : add useless pop/swap insn elimination with stack caching
+
+ * depend : remove compiled.o dependency
+
+
2005-06-26(Sun) 14:06:22 +0900 Koichi Sasada <ko1 atdot.net>
* benchmark/run.rb : use tmpfile instead of popen
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-06-26 05:13:28 UTC (rev 172)
+++ trunk/compile.c 2005-06-27 07:55:26 UTC (rev 173)
@@ -1302,18 +1302,18 @@
#include "opt_sc.inc"
-int insn_set_sc_state(struct insn_object *iobj, int state){
+int insn_set_sc_state(INSN_OBJECT *iobj, int state){
int nstate;
int insn_id;
- insn_id = iobj->insn_id;
+ insn_id = iobj->insn_id;
iobj->insn_id = SC_INSN(insn_id, state);
nstate = SC_NEXT(iobj->insn_id);
if(insn_id == BIN(jump) ||
insn_id == BIN(if) ||
insn_id == BIN(unless)){
- struct label_object *lobj = (LABEL_OBJECT*) OPERAND_AT(iobj, 0);
+ LABEL_OBJECT *lobj = (LABEL_OBJECT*) OPERAND_AT(iobj, 0);
if(lobj->sc_state != 0){
if(lobj->sc_state != nstate){
@@ -1368,26 +1368,12 @@
redo_point:
switch(list->type){
case ISEQ_ELEMENT_INSN:{
- struct insn_object *iobj;
- iobj = (struct insn_object *)list;
+ INSN_OBJECT *iobj = (INSN_OBJECT *)list;
insn_id = iobj->insn_id;
// iseq_disasm_list_dump(list);
switch(insn_id){
- case BIN(jump):
- case BIN(if):
- case BIN(unless):{
- if(state == SCS_BA){
- struct insn_object *siobj = new_insn_body(iseqobj, 0, BIN(swap), 0);
-
- /* insert this insn */
- INSERT_ELEM_PREV(list, (ISEQ_LINK_ELEMENT *)siobj);
- list = (ISEQ_LINK_ELEMENT *)siobj;
- goto redo_point;
- }
- break;
- }
case BIN(nop):{
/* exception merge point */
if(state != SCS_AX){
@@ -1400,7 +1386,42 @@
}
break;
}
+ case BIN(swap):{
+ if(state == SCS_AB || state == SCS_BA){
+ state = (state == SCS_AB ? SCS_BA : SCS_AB);
+
+ REMOVE_ELEM(list);
+ list = list->next;
+ goto redo_point;
+ }
+ break;
+ }
+ case BIN(pop):{
+ switch(state){
+ case SCS_AX:
+ case SCS_BX:
+ state = SCS_XX;
+ break;
+ case SCS_AB:
+ state = SCS_AX;
+ break;
+ case SCS_BA:
+ state = SCS_BX;
+ break;
+ case SCS_XX:
+ goto normal_insn;
+ default:
+ rb_bug("unreachable");
+ }
+ /* remove useless pop */
+ REMOVE_ELEM(list);
+ list = list->next;
+ goto redo_point;
+ }
+ default:;
+ /* none */
} /* end of switch */
+ normal_insn:
state = insn_set_sc_state(iobj, state);
break;
}
Modified: trunk/depend
===================================================================
--- trunk/depend 2005-06-26 05:13:28 UTC (rev 172)
+++ trunk/depend 2005-06-27 07:55:26 UTC (rev 173)
@@ -4,7 +4,7 @@
yarvcore.o: yarvcore.c yarvcore.h version.h debug.h rev.inc
debug.o: debug.h
yarvsubst.o: yarv.h
-compiled.o: compiled.inc
+# compiled.o: compiled.inc
jitcompile.o: insns.inc
INSNS2VMOPT = $(CPPFLAGS) --srcdir=$(srcdir)
Modified: trunk/extconf.rb
===================================================================
--- trunk/extconf.rb 2005-06-26 05:13:28 UTC (rev 172)
+++ trunk/extconf.rb 2005-06-27 07:55:26 UTC (rev 173)
@@ -86,6 +86,8 @@
# for GCC
vm.asm:
$(CC) $(CFLAGS) -fno-crossjumping $(CPPFLAGS) -dA -S -o vm.asm.txt $(srcdir)/vm.c
+vm.cpp:
+ $(CPP) $(CPPFLAGS) $(CFLAGS) $(srcdir)/vm.c > vm.cpp.txt
EOS
}
Modified: trunk/rb/aotcompile.rb
===================================================================
--- trunk/rb/aotcompile.rb 2005-06-26 05:13:28 UTC (rev 172)
+++ trunk/rb/aotcompile.rb 2005-06-27 07:55:26 UTC (rev 173)
@@ -71,6 +71,7 @@
parsed = YARVCore::parse(File.read(file), file, 1)
p parsed
+ p parsed.insns
parsed = parsed.insns[0].operands[1]
ret = ''
@@ -147,6 +148,7 @@
end
if __FILE__ == $0
+ exit # now, unsupported
aot_compiler = YARVCore::AOTCompiler.new
open('compiled.inc', 'w'){|f|
f.puts aot_compiler.compile(File.join(File.dirname($0), 'aotctest.rb'))
Modified: trunk/rb/insns2vm.rb
===================================================================
--- trunk/rb/insns2vm.rb 2005-06-26 05:13:28 UTC (rev 172)
+++ trunk/rb/insns2vm.rb 2005-06-27 07:55:26 UTC (rev 173)
@@ -3,6 +3,7 @@
#
#
# $verbose = true
+# $use_const = true
require 'pp'
require 'erb'
@@ -278,7 +279,7 @@
def make_unified_insns insns
- if false || true # all optimized insn
+ if false # || true # all optimized insn
insn_sets = insns.map{|insn|
[insn] + insn.optimized
}
@@ -298,7 +299,7 @@
v = v.dup
if v[0] != '...'
- redef[v[1]] = 1
+ redef[v[1]] = v[0]
v[1] = "#{v[1]}_#{i}"
end
v
@@ -314,7 +315,7 @@
pv = v.dup
v = pv[0] = pv[0].dup
if v[0] != '...'
- redef[v[1]] = 1
+ redef[v[1]] = v[0]
v[1] = "#{v[1]}_#{i}"
end
pv
@@ -367,16 +368,16 @@
defopes.concat e_defs
body += #
+ "{ /* unif: #{i} */\n" +
passed_vars.map{|rpvars|
pv = rpvars[0]
rv = rpvars[1]
- "#define #{pv[1]} #{rv[1]}\n"
+ "#define #{pv[1]} #{rv[1]}"
}.join("\n") +
"\n" +
- redef_vars.keys.map{|v|
+ redef_vars.map{|v, type|
"#define #{v} #{v}_#{i}"
- }.join("\n") +
- "\n" +
+ }.join("\n") + "\n" +
insn.body +
passed_vars.map{|rpvars|
"#undef #{rpvars[0][1]}"
@@ -385,7 +386,7 @@
redef_vars.keys.map{|v|
"#undef #{v}"
}.join("\n") +
- "\n"
+ "\n}\n"
}
tvars_ary = []
@@ -579,21 +580,28 @@
vars.each{|e|
next if e[1] == '*'
- ret << "#define #{e[0][1]} #{e[1]}"
- # " const #{e[0][0]} #{e[0][1]} = #{e[1]};\n"
+ if $use_const
+ ret << " const #{e[0][0]} #{e[0][1]} = #{e[1]};"
+ else
+ ret << " #define #{e[0][1]} #{e[1]}"
+ end
}
ret.join("\n") + "\n"
end
def make_footer_default_operands insn
- ret = []
- vars = insn.defopes
-
- vars.each{|e|
- next if e[1] == '*'
- ret << "#undef #{e[0][1]}\n"
- }
- ret.join("\n") + "\n"
+ if $use_const
+ "\n"
+ else
+ ret = []
+ vars = insn.defopes
+
+ vars.each{|e|
+ next if e[1] == '*'
+ ret << "#undef #{e[0][1]}\n"
+ }
+ ret.join("\n") + "\n"
+ end
end
def make_header_stack_pops insn
@@ -966,7 +974,8 @@
sc_insn_info = sc_insn_info.join(",\n")
sc_insn_next = @insns.map{|insn|
- " SCS_#{complement_name(insn.nextsc).upcase}"
+ " SCS_#{complement_name(insn.nextsc).upcase}" +
+ ($verbose ? " /* #{insn.name} */" : '')
}.join(",\n")
ERB.new(File.read($srcdir + '/tmpl/opt_sc.inc.tmpl')).result(binding)
end
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-06-26 05:13:28 UTC (rev 172)
+++ trunk/test.rb 2005-06-27 07:55:26 UTC (rev 173)
@@ -8,375 +8,9 @@
$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)
-}
+a = b = c = d = 1
-__END__
-
-def fact(n)
- if(n > 1)
- n * fact(n-1)
- else
- 1
- end
-end
-
-fact(7)
-__END__
-class C
- def m
- 1
- end
-end
-
-class CC < C
- def m
- super()
- end
-end
-
-obj = CC.new
-
-i = 0
-while i<10000000
- obj.m
- i+=1
-end
-
-__END__
-i=0
-while i<100
- i+=1
- #a = [1,2,3,4,5,6,7,8,9,10]
-end
-
-__END__
-
-def m
- /a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
- [$1, $2, $3, $~.class, $&, $`, $', $+]
- end
- m
-
-__END__
-a = 1
-b = 2
-a, b = b, a
-[a, b]
-__END__
-for i in [1, 2, 3]
- p i
-end
-
-__END__
- sum = 0
- for x in [1, 2, 3]
- sum += x
- end
- sum
-__END__
-ary = [ 1,2 ]
-for b in ary
- p 'hello'
- p b
-end
-
-__END__
-ary.each{|i|
- p 'each'
-}
-
-__END__
-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
-end
-
-__END__
-a = b = c = 1
-if (a or (b and c) or (a and b or c))
- p :then
-else
- p :else
-end
-
-p [a, b, c]
-
-__END__
-
-a, *b = 1, 2, *[3, 4, 5]
-p [a, b]
-__END__
-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
-o = C.new
-o.a ||= 2
-__END__
-#
-# RubiMaVM
-#
-
-module RubiMaVM
- class Instruction
- def initialize code, opts
- @code = code
- @opts = opts
- end
- attr_reader :code, :opts
-
- def inspect
- "#{code} <#{opts.join ', '}>"
- end
- end
-
- class Label
- @@id = 0
- def initialize label
- @label = label
- @pos = -1
- @id = @@id+=1
- end
- attr_accessor :pos
-
- def inspect
- "#{@label} <#{@id}@#{@pos}>"
- end
- alias to_s inspect
- end
-
- class Evaluator
- def initialize
- @stack = []
- @pc = 0
- end
-
- def evaluate sequence
- while insn = sequence[@pc]
- dispatch insn
- end
- @stack[0]
- end
-
- def dispatch insn
- case insn.code
- when :nop
-
- when :push
- push insn.opts[0]
-
- when :pop
- pop
-
- when :dup
- popped = pop
- push popped
- push popped
-
- when :add
- push pop + pop
-
- when :sub
- push pop - pop
-
- when :mul
- push pop * pop
-
- when :div
- push pop / pop
-
- when :not
- push !pop
-
- when :smaller
- push pop < pop
-
- when :bigger
- push pop > pop
-
- when :getlocal
- getlocal insn.opts[0]
- when :goto
- @pc = insn.opts[0].pos
- return
-
- when :if
- if pop
- @pc = insn.opts[0].pos
- return
- end
-
- when :send
- args = []
- insn.opts[1].times{
- args << pop
- }
- pop.__send__ *args
-
- else
- raise "Unknown Opcode: #{insn}"
-
- end
-
- @pc += 1
- end
-
- def push obj
- @stack.push obj
- end
-
- def pop
- @stack.pop
- end
- end
-
- class Parser
- def self.parse program
- pc = 0
- labels = {}
- program.map{|line|
- line = line.strip
- insn = []
-
- if /\A:\w+\z/ =~ line
- label = $~[0].intern
- unless lobj = labels[label]
- lobj = Label.new label
- labels[label] = lobj
- end
- next lobj
- end
-
- while line.size > 0
- case line
- when /\A:[a-z]+/
- # label
- label = $~[0].intern
- unless lobj = labels[label]
- lobj = Label.new label
- labels[label] = lobj
- end
- insn << lobj
- when /\A\s+/, /\A\#.*/
- # ignore
- when /\A[a-z]+/
- insn << $~[0].intern
- when /\A\d+/
- insn << $~[0].to_i
- else
- raise "Parse Error: #{line}"
- end
- line = $~.post_match
- end
-
- insn.size > 0 ? insn : nil
- }.compact.map{|insn|
- if insn.kind_of? Label
- insn.pos = pc
- nil
- else
- pc += 1
- Instruction.new insn[0], insn[1..-1]
- end
- }.compact
- end
- end
-end
-
-
-if $0 == __FILE__
- program = <<-EOP
- #
- push 1
- :label
- push 1
- add
- dup
- push 100#000
- bigger
- if :label
- EOP
-
- parsed_program = RubiMaVM::Parser.parse program
- if false
- parsed_program.each_with_index{|insn, idx|
- puts "#{'%04d' % idx}\t#{insn.inspect}"
- }
-
- result = RubiMaVM::Evaluator.new.evaluate parsed_program
- puts result
- end
-end
-
-
-
__EOP__
###########################################################
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml