summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-12-11 20:30:37 (GMT)
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-12-11 20:30:37 (GMT)
commit568c0a2dff72459d65e58c0c828144cc5a19438c (patch)
treec0505a2b3643a61d3fa72c2151e4227a86d546ba /vm_insnhelper.c
parent975e3a19a7ef725f6358d74f5bf7fd20d4403587 (diff)
remove vm_opt_binop_dispatch().
* vm_insnhelper.c (vm_opt_binop_dispatch): removed because this function has several issues for micro-benchmark. Write conditions manually. The worst point is that we can't control value checking order. For example, we can assume FIXNUM arithmetic operations are most popular in Ruby, so that we need to check FIXNUM at first. * test/ruby/test_optimization.rb: also fix redef bug for LE/GT/GE. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61123 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c248
1 files changed, 151 insertions, 97 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 40175ad..377f58e 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3345,95 +3345,107 @@ vm_stack_consistency_error(const rb_execution_context_t *ec,
#endif
}
-enum binop_operands_type {
- bot_others = 0,
- bot_fixnum,
- bot_flonum,
- bot_float
-};
-
-static enum binop_operands_type
-vm_opt_binop_dispatch(VALUE recv, VALUE obj, enum ruby_basic_operators BOP)
+static VALUE
+vm_opt_plus(VALUE recv, VALUE obj)
{
if (FIXNUM_2_P(recv, obj) &&
- BASIC_OP_UNREDEFINED_P(BOP, INTEGER_REDEFINED_OP_FLAG)) {
- return bot_fixnum;
+ BASIC_OP_UNREDEFINED_P(BOP_PLUS, INTEGER_REDEFINED_OP_FLAG)) {
+ return rb_fix_plus_fix(recv, obj);
}
else if (FLONUM_2_P(recv, obj) &&
- BASIC_OP_UNREDEFINED_P(BOP, FLOAT_REDEFINED_OP_FLAG)) {
- return bot_flonum;
+ BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
}
else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
- return bot_others;
+ return Qundef;
}
else if (RBASIC_CLASS(recv) == rb_cFloat &&
RBASIC_CLASS(obj) == rb_cFloat &&
- BASIC_OP_UNREDEFINED_P(BOP, FLOAT_REDEFINED_OP_FLAG)) {
- return bot_float;
+ BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
}
- else {
- return bot_others;
+ else if (RBASIC_CLASS(recv) == rb_cString &&
+ RBASIC_CLASS(obj) == rb_cString &&
+ BASIC_OP_UNREDEFINED_P(BOP_PLUS, STRING_REDEFINED_OP_FLAG)) {
+ return rb_str_plus(recv, obj);
}
-}
-
-static VALUE
-vm_opt_plus(VALUE recv, VALUE obj)
-{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_PLUS)) {
- case bot_float:
- case bot_flonum: return DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
- case bot_fixnum: return rb_fix_plus_fix(recv, obj);
- default:
- if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
- return Qundef;
- }
- else if (RBASIC_CLASS(recv) == rb_cString &&
- RBASIC_CLASS(obj) == rb_cString &&
- BASIC_OP_UNREDEFINED_P(BOP_PLUS, STRING_REDEFINED_OP_FLAG)) {
- return rb_str_plus(recv, obj);
- }
- else if (RBASIC_CLASS(recv) == rb_cArray &&
- BASIC_OP_UNREDEFINED_P(BOP_PLUS, ARRAY_REDEFINED_OP_FLAG)) {
- return rb_ary_plus(recv, obj);
- }
- else {
- return Qundef;
- }
+ else if (RBASIC_CLASS(recv) == rb_cArray &&
+ BASIC_OP_UNREDEFINED_P(BOP_PLUS, ARRAY_REDEFINED_OP_FLAG)) {
+ return rb_ary_plus(recv, obj);
+ }
+ else {
+ return Qundef;
}
}
static VALUE
vm_opt_minus(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_MINUS)) {
- case bot_float:
- case bot_flonum: return DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
- case bot_fixnum: return rb_fix_minus_fix(recv, obj);
- default: return Qundef;
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_MINUS, INTEGER_REDEFINED_OP_FLAG)) {
+ return rb_fix_minus_fix(recv, obj);
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
+ }
+ else {
+ return Qundef;
}
}
static VALUE
vm_opt_mult(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_MULT)) {
- case bot_float:
- case bot_flonum: return DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
- case bot_fixnum: return rb_fix_mul_fix(recv, obj);
- default: return Qundef;
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_MULT, INTEGER_REDEFINED_OP_FLAG)) {
+ return rb_fix_mul_fix(recv, obj);
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
+ }
+ else {
+ return Qundef;
}
}
static VALUE
vm_opt_div(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_DIV)) {
- case bot_float:
- case bot_flonum:
- return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
- case bot_fixnum:
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_DIV, INTEGER_REDEFINED_OP_FLAG)) {
return (FIX2LONG(obj) == 0) ? Qundef : rb_fix_div_fix(recv, obj);
- default:
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
+ }
+ else {
return Qundef;
}
}
@@ -3441,13 +3453,23 @@ vm_opt_div(VALUE recv, VALUE obj)
static VALUE
vm_opt_mod(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_MOD)) {
- case bot_float:
- case bot_flonum:
- return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
- case bot_fixnum:
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_MOD, INTEGER_REDEFINED_OP_FLAG)) {
return (FIX2LONG(obj) == 0) ? Qundef : rb_fix_mod_fix(recv, obj);
- default:
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
+ return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
+ }
+ else {
return Qundef;
}
}
@@ -3471,16 +3493,24 @@ vm_opt_neq(CALL_INFO ci, CALL_CACHE cc,
static VALUE
vm_opt_lt(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_LT)) {
- case bot_float:
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_LT, INTEGER_REDEFINED_OP_FLAG)) {
+ return (SIGNED_VALUE)recv < (SIGNED_VALUE)obj ? Qtrue : Qfalse;
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
+ return RFLOAT_VALUE(recv) < RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
CHECK_CMP_NAN(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
- /* FALLTHROUGH */
- case bot_flonum:
- /* flonum is not NaN */
return RFLOAT_VALUE(recv) < RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
- case bot_fixnum:
- return (SIGNED_VALUE)recv < (SIGNED_VALUE)obj ? Qtrue : Qfalse;
- default:
+ }
+ else {
return Qundef;
}
}
@@ -3488,16 +3518,24 @@ vm_opt_lt(VALUE recv, VALUE obj)
static VALUE
vm_opt_le(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_LT)) {
- case bot_float:
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_LE, INTEGER_REDEFINED_OP_FLAG)) {
+ return (SIGNED_VALUE)recv <= (SIGNED_VALUE)obj ? Qtrue : Qfalse;
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_LE, FLOAT_REDEFINED_OP_FLAG)) {
+ return RFLOAT_VALUE(recv) <= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_LE, FLOAT_REDEFINED_OP_FLAG)) {
CHECK_CMP_NAN(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
- /* FALLTHROUGH */
- case bot_flonum:
- /* flonum is not NaN */
return RFLOAT_VALUE(recv) <= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
- case bot_fixnum:
- return (SIGNED_VALUE)recv <= (SIGNED_VALUE)obj ? Qtrue : Qfalse;
- default:
+ }
+ else {
return Qundef;
}
}
@@ -3505,16 +3543,24 @@ vm_opt_le(VALUE recv, VALUE obj)
static VALUE
vm_opt_gt(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_LT)) {
- case bot_float:
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_GT, INTEGER_REDEFINED_OP_FLAG)) {
+ return (SIGNED_VALUE)recv > (SIGNED_VALUE)obj ? Qtrue : Qfalse;
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
+ return RFLOAT_VALUE(recv) > RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
CHECK_CMP_NAN(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
- /* FALLTHROUGH */
- case bot_flonum:
- /* flonum is not NaN */
return RFLOAT_VALUE(recv) > RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
- case bot_fixnum:
- return (SIGNED_VALUE)recv > (SIGNED_VALUE)obj ? Qtrue : Qfalse;
- default:
+ }
+ else {
return Qundef;
}
}
@@ -3522,16 +3568,24 @@ vm_opt_gt(VALUE recv, VALUE obj)
static VALUE
vm_opt_ge(VALUE recv, VALUE obj)
{
- switch (vm_opt_binop_dispatch(recv, obj, BOP_LT)) {
- case bot_float:
+ if (FIXNUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_GE, INTEGER_REDEFINED_OP_FLAG)) {
+ return (SIGNED_VALUE)recv >= (SIGNED_VALUE)obj ? Qtrue : Qfalse;
+ }
+ else if (FLONUM_2_P(recv, obj) &&
+ BASIC_OP_UNREDEFINED_P(BOP_GE, FLOAT_REDEFINED_OP_FLAG)) {
+ return RFLOAT_VALUE(recv) >= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+ }
+ else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) {
+ return Qundef;
+ }
+ else if (RBASIC_CLASS(recv) == rb_cFloat &&
+ RBASIC_CLASS(obj) == rb_cFloat &&
+ BASIC_OP_UNREDEFINED_P(BOP_GE, FLOAT_REDEFINED_OP_FLAG)) {
CHECK_CMP_NAN(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
- /* FALLTHROUGH */
- case bot_flonum:
- /* flonum is not NaN */
return RFLOAT_VALUE(recv) >= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
- case bot_fixnum:
- return (SIGNED_VALUE)recv >= (SIGNED_VALUE)obj ? Qtrue : Qfalse;
- default:
+ }
+ else {
return Qundef;
}
}