[前][次][番号順一覧][スレッド一覧]

ruby-changes:50538

From: k0kubun <ko1@a...>
Date: Tue, 6 Mar 2018 21:53:26 +0900 (JST)
Subject: [ruby-changes:50538] k0kubun:r62677 (trunk): transform_mjit_header.rb: inline VM instructions

k0kubun	2018-03-06 21:53:19 +0900 (Tue, 06 Mar 2018)

  New Revision: 62677

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62677

  Log:
    transform_mjit_header.rb: inline VM instructions
    
    * Optcarrot benchmark (--jit)
    
    Before: 62.42 fps
    After: 65.31 fps

  Modified files:
    trunk/tool/transform_mjit_header.rb
Index: tool/transform_mjit_header.rb
===================================================================
--- tool/transform_mjit_header.rb	(revision 62676)
+++ tool/transform_mjit_header.rb	(revision 62677)
@@ -20,6 +20,11 @@ module MJITHeader https://github.com/ruby/ruby/blob/trunk/tool/transform_mjit_header.rb#L20
     '__clang__', # clang
   ]
 
+  # These macros are relied on this script's transformation
+  PREFIXED_MACROS = [
+    'ALWAYS_INLINE',
+  ]
+
   # For MinGW's ras.h. Those macros have its name in its definition and can't be preprocessed multiple times.
   RECURSIVE_MACROS = %w[
     RASCTRYINFO
@@ -31,6 +36,25 @@ module MJITHeader https://github.com/ruby/ruby/blob/trunk/tool/transform_mjit_header.rb#L36
     'rb_equal_opt', # Not used from VM and not compilable
   ]
 
+  ALWAYS_INLINED_FUNCTIONS = [
+    'vm_opt_plus',
+    'vm_opt_minus',
+    'vm_opt_mult',
+    'vm_opt_div',
+    'vm_opt_mod',
+    'vm_opt_neq',
+    'vm_opt_lt',
+    'vm_opt_le',
+    'vm_opt_gt',
+    'vm_opt_ge',
+    'vm_opt_ltlt',
+    'vm_opt_aref',
+    'vm_opt_aset',
+    'vm_opt_aref_with',
+    'vm_opt_aset_with',
+    'vm_opt_not',
+  ]
+
   # Return start..stop of last decl in CODE ending STOP
   def self.find_decl(code, stop)
     level = 0
@@ -106,9 +130,11 @@ module MJITHeader https://github.com/ruby/ruby/blob/trunk/tool/transform_mjit_header.rb#L130
     code.sub!(/\A(#define [^\n]+|\n)*(#define MJIT_HEADER 1\n)/, '\2')
   end
 
-  # This makes easier to process code
+  # Return [macro, others]. But others include PREFIXED_MACROS to be used in code.
   def self.separate_macro_and_code(code)
-    code.lines.partition { |l| l.start_with?('#') }.map! {|lines| lines.join('')}
+    code.lines.partition do |l|
+      l.start_with?('#') && PREFIXED_MACROS.all? { |m| !l.start_with?("#define #{m}") }
+    end.map! { |lines| lines.join('') }
   end
 
   def self.write(code, out)
@@ -203,6 +229,11 @@ while (decl_range = MJITHeader.find_decl https://github.com/ruby/ruby/blob/trunk/tool/transform_mjit_header.rb#L229
   if MJITHeader::IGNORED_FUNCTIONS.include?(decl_name) && /#{MJITHeader::FUNC_HEADER_REGEXP}{/.match(decl)
     puts "#{PROGRAM}: changing definition of '#{decl_name}' to declaration"
     code[decl_range] = decl.sub(/{.+}/m, ';')
+  elsif MJITHeader::ALWAYS_INLINED_FUNCTIONS.include?(decl_name) && match = /#{MJITHeader::FUNC_HEADER_REGEXP}{/.match(decl)
+    header = match[0].sub(/{\z/, '').strip
+    header = "static inline #{header.sub(/\A((static|inline) )+/, '')}"
+    decl[match.begin(0)...match.end(0)] = '{' # remove header
+    code[decl_range] = "\nALWAYS_INLINE(#{header});\n#{header} #{decl}"
   elsif extern_names.include?(decl_name) && (decl =~ /#{MJITHeader::FUNC_HEADER_REGEXP};/)
     decl.sub!(/(extern|static|inline) /, ' ')
     unless decl_name =~ /\Aattr_\w+_\w+\z/ # skip too-many false-positive warnings in insns_info.inc.

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]