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

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

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