From dbb4f1996939d0ce977e6b37579e28dd886428ff Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Tue, 22 Dec 2020 22:23:45 -0800 Subject: 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 ``` --- benchmark/mjit_integer.yml | 4 ++++ integer.rb | 25 +++++++++++++++++++++++++ internal/numeric.h | 3 ++- numeric.c | 34 ++++------------------------------ 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); -- cgit v1.2.3