summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authork0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-25 17:19:51 +0000
committerk0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-25 17:19:51 +0000
commit08c9f030f6b5d260d12cf02a9ca0f4a60f816365 (patch)
tree42e5f6136b38effe27dac1617ce5ddd44fac6323
parent3f4d174c22589ea275f971fab90136add6e456ac (diff)
Revert "Revert r64824 to fix build failure on AppVeyor"
This reverts commit r64829. I'll prepare another temporary fix, but I'll separately commit that to make it easier to revert that later. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64838 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--compile.c2
-rw-r--r--defs/id.def2
-rw-r--r--insns.def28
-rw-r--r--test/ruby/test_jit.rb8
-rw-r--r--test/ruby/test_optimization.rb10
-rw-r--r--tool/transform_mjit_header.rb2
-rw-r--r--vm.c2
-rw-r--r--vm_core.h2
-rw-r--r--vm_insnhelper.c24
9 files changed, 80 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 83d992a..0a2e076 100644
--- a/compile.c
+++ b/compile.c
@@ -3245,6 +3245,8 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
case idGE: SP_INSN(ge); return COMPILE_OK;
case idLTLT: SP_INSN(ltlt); return COMPILE_OK;
case idAREF: SP_INSN(aref); return COMPILE_OK;
+ case idAnd: SP_INSN(and); return COMPILE_OK;
+ case idOr: SP_INSN(or); return COMPILE_OK;
}
break;
case 2:
diff --git a/defs/id.def b/defs/id.def
index e1a66f5..fe61d25 100644
--- a/defs/id.def
+++ b/defs/id.def
@@ -97,6 +97,8 @@ token_ops = %[\
Eqq === EQQ
Neq != NEQ
Not !
+ And &
+ Or |
Backquote `
EqTilde =~ MATCH
NeqTilde !~ NMATCH
diff --git a/insns.def b/insns.def
index 742cd87..cacc5b7 100644
--- a/insns.def
+++ b/insns.def
@@ -1216,6 +1216,34 @@ opt_ltlt
}
}
+/* optimized X&Y. */
+DEFINE_INSN
+opt_and
+(CALL_INFO ci, CALL_CACHE cc)
+(VALUE recv, VALUE obj)
+(VALUE val)
+{
+ val = vm_opt_and(recv, obj);
+
+ if (val == Qundef) {
+ CALL_SIMPLE_METHOD();
+ }
+}
+
+/* optimized X|Y. */
+DEFINE_INSN
+opt_or
+(CALL_INFO ci, CALL_CACHE cc)
+(VALUE recv, VALUE obj)
+(VALUE val)
+{
+ val = vm_opt_or(recv, obj);
+
+ if (val == Qundef) {
+ CALL_SIMPLE_METHOD();
+ }
+}
+
/* [] */
DEFINE_INSN
opt_aref
diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb
index 50f318c..3770faf 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_jit.rb
@@ -478,6 +478,14 @@ class TestJIT < Test::Unit::TestCase
assert_compile_once('[1] << 2', result_inspect: '[1, 2]', insns: %i[opt_ltlt])
end
+ def test_compile_insn_opt_and
+ assert_compile_once('1 & 3', result_inspect: '1', insns: %i[opt_and])
+ end
+
+ def test_compile_insn_opt_or
+ assert_compile_once('1 | 3', result_inspect: '3', insns: %i[opt_or])
+ end
+
def test_compile_insn_opt_aref
skip_on_mswin
# optimized call (optimized JIT) -> send call
diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb
index d4a1fdb..c425254 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -187,6 +187,16 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_redefine_method('String', '<<', 'assert_equal "b", "a" << "b"')
end
+ def test_fixnum_and
+ assert_equal 1, 1&3
+ assert_redefine_method('Integer', '&', 'assert_equal 3, 1&3')
+ end
+
+ def test_fixnum_or
+ assert_equal 3, 1|3
+ assert_redefine_method('Integer', '|', 'assert_equal 1, 3|1')
+ end
+
def test_array_plus
assert_equal [1,2], [1]+[2]
assert_redefine_method('Array', '+', 'assert_equal [2], [1]+[2]')
diff --git a/tool/transform_mjit_header.rb b/tool/transform_mjit_header.rb
index 936a0e1..1000172 100644
--- a/tool/transform_mjit_header.rb
+++ b/tool/transform_mjit_header.rb
@@ -52,6 +52,8 @@ module MJITHeader
'vm_opt_gt',
'vm_opt_ge',
'vm_opt_ltlt',
+ 'vm_opt_and',
+ 'vm_opt_or',
'vm_opt_aref',
'vm_opt_aset',
'vm_opt_aref_with',
diff --git a/vm.c b/vm.c
index da9afe2..eb47a83 100644
--- a/vm.c
+++ b/vm.c
@@ -1610,6 +1610,8 @@ vm_init_redefined_flag(void)
OP(Max, MAX), (C(Array));
OP(Min, MIN), (C(Array));
OP(Call, CALL), (C(Proc));
+ OP(And, AND), (C(Integer));
+ OP(Or, OR), (C(Integer));
#undef C
#undef OP
}
diff --git a/vm_core.h b/vm_core.h
index bb64097..1ab49b0 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -531,6 +531,8 @@ enum ruby_basic_operators {
BOP_MAX,
BOP_MIN,
BOP_CALL,
+ BOP_AND,
+ BOP_OR,
BOP_LAST_
};
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 29b9358..29e6545 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3653,6 +3653,30 @@ vm_opt_ltlt(VALUE recv, VALUE obj)
}
static VALUE
+vm_opt_and(VALUE recv, VALUE obj)
+{
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_AND, INTEGER_REDEFINED_OP_FLAG)) {
+ return LONG2NUM(FIX2LONG(recv) & FIX2LONG(obj));
+ }
+ else {
+ return Qundef;
+ }
+}
+
+static VALUE
+vm_opt_or(VALUE recv, VALUE obj)
+{
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_OR, INTEGER_REDEFINED_OP_FLAG)) {
+ return LONG2NUM(FIX2LONG(recv) | FIX2LONG(obj));
+ }
+ else {
+ return Qundef;
+ }
+}
+
+static VALUE
vm_opt_aref(VALUE recv, VALUE obj)
{
if (SPECIAL_CONST_P(recv)) {