summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2020-12-22 22:23:45 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2020-12-22 22:32:19 -0800
commitdbb4f1996939d0ce977e6b37579e28dd886428ff (patch)
treec78f48a6f20b742c265596ea580e1fab318c239b
parentdaec109f423e54094800e083fc8a8ca5cbceb866 (diff)
Allow inlining Integer#-@ and #~
``` $ benchmark-driver -v --rbenv 'before --jit;after --jit' benchmark/mjit_integer.yml --filter '(comp|uminus)' before --jit: ruby 3.0.0dev (2020-12-23T05:41:44Z master 0dd4896175) +JIT [x86_64-linux] after --jit: ruby 3.0.0dev (2020-12-23T06:25:41Z master 8887d78992) +JIT [x86_64-linux] last_commit=Allow inlining Integer#-@ and #~ Calculating ------------------------------------- before --jit after --jit mjit_comp(1) 44.006M 70.417M i/s - 40.000M times in 0.908967s 0.568042s mjit_uminus(1) 44.333M 68.422M i/s - 40.000M times in 0.902255s 0.584603s Comparison: mjit_comp(1) after --jit: 70417331.4 i/s before --jit: 44005980.4 i/s - 1.60x slower mjit_uminus(1) after --jit: 68422468.8 i/s before --jit: 44333371.0 i/s - 1.54x slower ```
-rw-r--r--benchmark/mjit_integer.yml4
-rw-r--r--integer.rb25
-rw-r--r--internal/numeric.h3
-rw-r--r--numeric.c34
4 files changed, 35 insertions, 31 deletions
diff --git a/benchmark/mjit_integer.yml b/benchmark/mjit_integer.yml
index cd3288978b..edc3556479 100644
--- a/benchmark/mjit_integer.yml
+++ b/benchmark/mjit_integer.yml
@@ -2,6 +2,7 @@ type: lib/benchmark_driver/runner/mjit
prelude: |
def mjit_abs(int) int.abs end
def mjit_bit_length(int) int.bit_length end
+ def mjit_comp(int) ~int end
def mjit_even?(int) int.even? end
def mjit_integer?(int) int.integer? end
def mjit_magnitude(int) int.magnitude end
@@ -9,11 +10,13 @@ prelude: |
def mjit_ord(int) int.ord end
def mjit_to_i(int) int.to_i end
def mjit_to_int(int) int.to_int end
+ def mjit_uminus(int) -int end
def mjit_zero?(int) int.zero? end
benchmark:
- mjit_abs(-1)
- mjit_bit_length(100)
+ - mjit_comp(1)
- mjit_even?(2)
- mjit_integer?(0)
- mjit_magnitude(-1)
@@ -21,6 +24,7 @@ benchmark:
- mjit_ord(1)
- mjit_to_i(1)
- mjit_to_int(1)
+ - mjit_uminus(1)
- mjit_zero?(0)
loop_count: 40000000
diff --git a/integer.rb b/integer.rb
index b9cde8f390..d18494f42f 100644
--- a/integer.rb
+++ b/integer.rb
@@ -1,4 +1,29 @@
class Integer
+ # call-seq:
+ # -int -> integer
+ #
+ # Returns +int+, negated.
+ def -@
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_uminus(self)'
+ end
+
+ # call-seq:
+ # ~int -> integer
+ #
+ # One's complement: returns a number where each bit is flipped.
+ #
+ # Inverts the bits in an Integer. As integers are conceptually of
+ # infinite length, the result acts as if it had an infinite number of
+ # one bits to the left. In hex representations, this is displayed
+ # as two periods to the left of the digits.
+ #
+ # sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
+ def ~
+ Primitive.attr! 'inline'
+ Primitive.cexpr! 'rb_int_comp(self)'
+ end
+
def abs
Primitive.attr! 'inline'
Primitive.cexpr! 'rb_int_abs(self)'
diff --git a/internal/numeric.h b/internal/numeric.h
index 3dc72d22f5..32d5bd27fa 100644
--- a/internal/numeric.h
+++ b/internal/numeric.h
@@ -50,7 +50,6 @@ double ruby_float_step_size(double beg, double end, double unit, int excl);
int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless);
int rb_num_negative_p(VALUE);
VALUE rb_int_succ(VALUE num);
-VALUE rb_int_uminus(VALUE num);
VALUE rb_float_uminus(VALUE num);
VALUE rb_int_plus(VALUE x, VALUE y);
VALUE rb_float_plus(VALUE x, VALUE y);
@@ -112,6 +111,8 @@ VALUE rb_int_even_p(VALUE num);
VALUE rb_int_odd_p(VALUE num);
VALUE rb_int_abs(VALUE num);
VALUE rb_int_bit_length(VALUE num);
+VALUE rb_int_uminus(VALUE num);
+VALUE rb_int_comp(VALUE num);
MJIT_SYMBOL_EXPORT_END
static inline bool
diff --git a/numeric.c b/numeric.c
index d599e123f5..e4bb4817bb 100644
--- a/numeric.c
+++ b/numeric.c
@@ -3456,15 +3456,6 @@ int_chr(int argc, VALUE *argv, VALUE num)
* Fixnum
*/
-
-/*
- * Document-method: Integer#-@
- * call-seq:
- * -int -> integer
- *
- * Returns +int+, negated.
- */
-
static VALUE
fix_uminus(VALUE num)
{
@@ -3477,10 +3468,10 @@ rb_int_uminus(VALUE num)
if (FIXNUM_P(num)) {
return fix_uminus(num);
}
- else if (RB_TYPE_P(num, T_BIGNUM)) {
+ else {
+ assert(RB_TYPE_P(num, T_BIGNUM));
return rb_big_uminus(num);
}
- return num_funcall0(num, idUMinus);
}
/*
@@ -4371,29 +4362,14 @@ int_le(VALUE x, VALUE y)
return Qnil;
}
-/*
- * Document-method: Integer#~
- * call-seq:
- * ~int -> integer
- *
- * One's complement: returns a number where each bit is flipped.
- *
- * Inverts the bits in an Integer. As integers are conceptually of
- * infinite length, the result acts as if it had an infinite number of
- * one bits to the left. In hex representations, this is displayed
- * as two periods to the left of the digits.
- *
- * sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
- */
-
static VALUE
fix_comp(VALUE num)
{
return ~num | FIXNUM_FLAG;
}
-static VALUE
-int_comp(VALUE num)
+VALUE
+rb_int_comp(VALUE num)
{
if (FIXNUM_P(num)) {
return fix_comp(num);
@@ -5576,7 +5552,6 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "round", int_round, -1);
rb_define_method(rb_cInteger, "<=>", rb_int_cmp, 1);
- rb_define_method(rb_cInteger, "-@", rb_int_uminus, 0);
rb_define_method(rb_cInteger, "+", rb_int_plus, 1);
rb_define_method(rb_cInteger, "-", rb_int_minus, 1);
rb_define_method(rb_cInteger, "*", rb_int_mul, 1);
@@ -5598,7 +5573,6 @@ Init_Numeric(void)
rb_define_method(rb_cInteger, "<", int_lt, 1);
rb_define_method(rb_cInteger, "<=", int_le, 1);
- rb_define_method(rb_cInteger, "~", int_comp, 0);
rb_define_method(rb_cInteger, "&", rb_int_and, 1);
rb_define_method(rb_cInteger, "|", int_or, 1);
rb_define_method(rb_cInteger, "^", int_xor, 1);