1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/tool/ruby_vm/views/_mjit_compile_ivar.erb

55 lines
2.7 KiB
Text
Raw Normal View History

% # -*- C -*-
_mjit_compile_getivar.erb: optimize IC-hit getivar by inlining index (and serial to invalidate that) and simplifying the branch by using JIT cancellation. mjit_compile.inc.erb: use the above file mjit_compile.c: copy USE_IC_FOR_IVAR definition. will move this to another shared file later. common.mk: add new dependency test/ruby/test_jit.rb: cover this case === Optcarrot benchmark === ``` $ benchmark-driver benchmark.yml --rbenv '2.0.0::2.0.0-p648;before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24 2.0.0: ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] before: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar after+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar Calculating ------------------------------------- 2.0.0 before before+JIT after after+JIT Optcarrot Lan_Master.nes 36.065 53.896 71.565 53.856 84.747 fps Comparison: Optcarrot Lan_Master.nes after+JIT: 84.7 fps before+JIT: 71.6 fps - 1.18x slower before: 53.9 fps - 1.57x slower after: 53.9 fps - 1.57x slower 2.0.0: 36.1 fps - 2.35x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:24:43 -04:00
% # Copyright (c) 2018 Takashi Kokubun. All rights reserved.
% #
% # This file is a part of the programming language Ruby. Permission is hereby
% # granted, to either redistribute and/or modify this file, provided that the
% # conditions mentioned in the file COPYING are met. Consult the file for
% # details.
%
% # Optimized case of get_instancevariable instruction.
#if OPT_IC_FOR_IVAR
_mjit_compile_getivar.erb: optimize IC-hit getivar by inlining index (and serial to invalidate that) and simplifying the branch by using JIT cancellation. mjit_compile.inc.erb: use the above file mjit_compile.c: copy USE_IC_FOR_IVAR definition. will move this to another shared file later. common.mk: add new dependency test/ruby/test_jit.rb: cover this case === Optcarrot benchmark === ``` $ benchmark-driver benchmark.yml --rbenv '2.0.0::2.0.0-p648;before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24 2.0.0: ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] before: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar after+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar Calculating ------------------------------------- 2.0.0 before before+JIT after after+JIT Optcarrot Lan_Master.nes 36.065 53.896 71.565 53.856 84.747 fps Comparison: Optcarrot Lan_Master.nes after+JIT: 84.7 fps before+JIT: 71.6 fps - 1.18x slower before: 53.9 fps - 1.57x slower after: 53.9 fps - 1.57x slower 2.0.0: 36.1 fps - 2.35x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:24:43 -04:00
{
% # compiler: Prepare operands which may be used by `insn.call_attribute`
% insn.opes.each_with_index do |ope, i|
MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>];
% end
% # compiler: Use copied IC to avoid race condition
IC ic_copy = &(status->is_entries + ((union iseq_inline_storage_entry *)ic - body->is_entries))->cache;
_mjit_compile_getivar.erb: optimize IC-hit getivar by inlining index (and serial to invalidate that) and simplifying the branch by using JIT cancellation. mjit_compile.inc.erb: use the above file mjit_compile.c: copy USE_IC_FOR_IVAR definition. will move this to another shared file later. common.mk: add new dependency test/ruby/test_jit.rb: cover this case === Optcarrot benchmark === ``` $ benchmark-driver benchmark.yml --rbenv '2.0.0::2.0.0-p648;before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24 2.0.0: ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] before: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar after+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar Calculating ------------------------------------- 2.0.0 before before+JIT after after+JIT Optcarrot Lan_Master.nes 36.065 53.896 71.565 53.856 84.747 fps Comparison: Optcarrot Lan_Master.nes after+JIT: 84.7 fps before+JIT: 71.6 fps - 1.18x slower before: 53.9 fps - 1.57x slower after: 53.9 fps - 1.57x slower 2.0.0: 36.1 fps - 2.35x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:24:43 -04:00
%
% # compiler: Consider cfp->self as T_OBJECT if ic_copy->ic_serial is set
Recompile JIT-ed code without optimization based on inline cache when JIT cancel happens by that. This feature was in the original MJIT implementation by Vladimir, but on merging MJIT to Ruby it was removed for simplification. This commit adds the functionality again for the following benchmark: https://github.com/benchmark-driver/misc/blob/52f05781f65467baf895bf6ba79d172c9b0826fd/concurrent-map/bench.rb (shown float is duration seconds. shorter is better) * Before ``` $ INHERIT=0 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] -- 1.6507579649914987 $ INHERIT=0 ruby -v --jit bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] -- 1.5091587850474752 $ INHERIT=1 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] -- 1.6124781150138006 $ INHERIT=1 ruby --jit -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] -- 1.7495657080435194 # <-- this ``` * After ``` $ INHERIT=0 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.653559010999743 $ INHERIT=0 ruby --jit -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.4738391840364784 $ INHERIT=1 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.645227018976584 $ INHERIT=1 ruby --jit -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.523708809982054 # <-- this ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67530 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-14 00:52:02 -04:00
if (!status->compile_info->disable_ivar_cache && ic_copy->ic_serial) {
_mjit_compile_getivar.erb: optimize IC-hit getivar by inlining index (and serial to invalidate that) and simplifying the branch by using JIT cancellation. mjit_compile.inc.erb: use the above file mjit_compile.c: copy USE_IC_FOR_IVAR definition. will move this to another shared file later. common.mk: add new dependency test/ruby/test_jit.rb: cover this case === Optcarrot benchmark === ``` $ benchmark-driver benchmark.yml --rbenv '2.0.0::2.0.0-p648;before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24 2.0.0: ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] before: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar after+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar Calculating ------------------------------------- 2.0.0 before before+JIT after after+JIT Optcarrot Lan_Master.nes 36.065 53.896 71.565 53.856 84.747 fps Comparison: Optcarrot Lan_Master.nes after+JIT: 84.7 fps before+JIT: 71.6 fps - 1.18x slower before: 53.9 fps - 1.57x slower after: 53.9 fps - 1.57x slower 2.0.0: 36.1 fps - 2.35x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:24:43 -04:00
% # JIT: optimize away motion of sp and pc. This path does not call rb_warning() and so it's always leaf and not `handles_sp`.
% # <%= render 'mjit_compile_pc_and_sp', locals: { insn: insn } -%>
%
% # JIT: prepare vm_getivar's arguments and variables
fprintf(f, "{\n");
fprintf(f, " VALUE obj = GET_SELF();\n");
fprintf(f, " const rb_serial_t ic_serial = (rb_serial_t)%"PRI_SERIALT_PREFIX"u;\n", ic_copy->ic_serial);
fprintf(f, " const st_index_t index = %"PRIuSIZE";\n", ic_copy->ic_value.index);
% # JIT: cache hit path of vm_getivar, or cancel JIT.
% if insn.name == 'setinstancevariable'
fprintf(f, " VALUE val = stack[%d];\n", b->stack_size - 1);
Check frozen flag on MJIT setinstancevariable It does not seem to have a significant performance impact, hopefully? ``` $ benchmark-driver -v benchmark.yml --rbenv 'before --jit;after --jit' --repeat-count=24 --output=all before --jit: ruby 2.7.0dev (2019-09-03T21:02:24Z master 77596fb7a9) +JIT [x86_64-linux] after --jit: ruby 2.7.0dev (2019-09-04T01:54:44Z master 7363e22d79) +JIT [x86_64-linux] Calculating ------------------------------------- before --jit after --jit Optcarrot Lan_Master.nes 48.44054595799523 71.67010255902900 fps 71.32797692837639 71.97846863769546 72.51921961607691 78.87360980544105 73.54082925611047 79.80408132389941 74.03503843709451 79.85739528572826 74.04863857926493 79.89850834901381 75.30266276129467 80.34607233076015 75.69063990896244 80.88474397425360 75.70458132587405 81.09234267781642 77.39842764662852 82.13766823612643 77.76922944068329 82.20398304840373 81.17984044023393 82.26722630628272 82.85235776076533 82.71375902781254 83.04906099135320 82.75893420702198 83.10214168136230 82.79668965325972 83.71456007558125 82.85131667916379 84.06658306760725 82.95676565411722 84.25690684305728 83.19972846225775 84.27938663923503 83.28510503845854 84.45467716218090 83.41003730434703 84.51563186125925 83.67773614721280 84.56139892968321 84.02082201151110 84.69819452180658 84.10495346787033 84.78125989622576 84.47867803506055 ``` Note for backporter: test_jit's `success_count` would be 1 in Ruby 2.6, since 2.7 introduced "MJIT recompile" on JIT-ed code cancel. [Bug #16139]
2019-09-03 21:53:20 -04:00
fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && !RB_OBJ_FROZEN(obj))) {\n");
fprintf(f, " VALUE *ptr = ROBJECT_IVPTR(obj);\n");
fprintf(f, " RB_OBJ_WRITE(obj, &ptr[index], val);\n");
fprintf(f, " }\n");
% else
fprintf(f, " VALUE val;\n");
fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && (val = ROBJECT_IVPTR(obj)[index]) != Qundef)) {\n");
fprintf(f, " stack[%d] = val;\n", b->stack_size);
_mjit_compile_getivar.erb: optimize IC-hit getivar by inlining index (and serial to invalidate that) and simplifying the branch by using JIT cancellation. mjit_compile.inc.erb: use the above file mjit_compile.c: copy USE_IC_FOR_IVAR definition. will move this to another shared file later. common.mk: add new dependency test/ruby/test_jit.rb: cover this case === Optcarrot benchmark === ``` $ benchmark-driver benchmark.yml --rbenv '2.0.0::2.0.0-p648;before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24 2.0.0: ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] before: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar after+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar Calculating ------------------------------------- 2.0.0 before before+JIT after after+JIT Optcarrot Lan_Master.nes 36.065 53.896 71.565 53.856 84.747 fps Comparison: Optcarrot Lan_Master.nes after+JIT: 84.7 fps before+JIT: 71.6 fps - 1.18x slower before: 53.9 fps - 1.57x slower after: 53.9 fps - 1.57x slower 2.0.0: 36.1 fps - 2.35x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:24:43 -04:00
fprintf(f, " }\n");
% end
_mjit_compile_getivar.erb: optimize IC-hit getivar by inlining index (and serial to invalidate that) and simplifying the branch by using JIT cancellation. mjit_compile.inc.erb: use the above file mjit_compile.c: copy USE_IC_FOR_IVAR definition. will move this to another shared file later. common.mk: add new dependency test/ruby/test_jit.rb: cover this case === Optcarrot benchmark === ``` $ benchmark-driver benchmark.yml --rbenv '2.0.0::2.0.0-p648;before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24 2.0.0: ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] before: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar after+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar Calculating ------------------------------------- 2.0.0 before before+JIT after after+JIT Optcarrot Lan_Master.nes 36.065 53.896 71.565 53.856 84.747 fps Comparison: Optcarrot Lan_Master.nes after+JIT: 84.7 fps before+JIT: 71.6 fps - 1.18x slower before: 53.9 fps - 1.57x slower after: 53.9 fps - 1.57x slower 2.0.0: 36.1 fps - 2.35x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:24:43 -04:00
fprintf(f, " else {\n");
fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos);
fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size);
fprintf(f, " goto ivar_cancel;\n");
_mjit_compile_getivar.erb: optimize IC-hit getivar by inlining index (and serial to invalidate that) and simplifying the branch by using JIT cancellation. mjit_compile.inc.erb: use the above file mjit_compile.c: copy USE_IC_FOR_IVAR definition. will move this to another shared file later. common.mk: add new dependency test/ruby/test_jit.rb: cover this case === Optcarrot benchmark === ``` $ benchmark-driver benchmark.yml --rbenv '2.0.0::2.0.0-p648;before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24 2.0.0: ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-linux] before: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-14 trunk 65072) [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar after+JIT: ruby 2.6.0dev (2018-10-14 trunk 65072) +JIT [x86_64-linux] last_commit=_mjit_compile_getivar.erb: optimize IC-hit getivar Calculating ------------------------------------- 2.0.0 before before+JIT after after+JIT Optcarrot Lan_Master.nes 36.065 53.896 71.565 53.856 84.747 fps Comparison: Optcarrot Lan_Master.nes after+JIT: 84.7 fps before+JIT: 71.6 fps - 1.18x slower before: 53.9 fps - 1.57x slower after: 53.9 fps - 1.57x slower 2.0.0: 36.1 fps - 2.35x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:24:43 -04:00
fprintf(f, " }\n");
% # compiler: Move JIT compiler's internal stack pointer
b->stack_size += <%= insn.call_attribute('sp_inc') %>;
fprintf(f, "}\n");
break;
}
}
#endif // OPT_IC_FOR_IVAR