diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-03-06 11:14:05 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-03-06 11:14:05 +0000 |
commit | 74cdd893eb102ba98e735f2a24c710e1928261a9 (patch) | |
tree | 148c82adfc714aaa2a3d60cda2c18c4f78ed9f76 /bignum.c | |
parent | cf2a68662aadcbed4a92cfdad4d992f894f3767f (diff) | |
download | ruby-74cdd893eb102ba98e735f2a24c710e1928261a9.tar.gz |
optimize FIXABLE macro
Looking at the source code, FIXABLE tends to be just before LOING2FIX
to check applicability of that operation. Why not try computing first
then check for overflow, which should be optimial.
I also tried the same thing for unsigned types but resulted in slower
execution. It seems RB_POSFIXABLE() is fast enough on modern CPUs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r-- | bignum.c | 16 |
1 files changed, 12 insertions, 4 deletions
@@ -3184,15 +3184,13 @@ rb_int2big(SIGNED_VALUE n) VALUE rb_uint2inum(VALUE n) { - if (POSFIXABLE(n)) return LONG2FIX(n); - return rb_uint2big(n); + return ULONG2NUM(n); } VALUE rb_int2inum(SIGNED_VALUE n) { - if (FIXABLE(n)) return LONG2FIX(n); - return rb_int2big(n); + return LONG2NUM(n); } void @@ -4438,8 +4436,18 @@ rb_ull2inum(unsigned LONG_LONG n) VALUE rb_ll2inum(LONG_LONG n) { +#ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW + SIGNED_VALUE v; + if (__builtin_mul_overflow(n, 2, &v)) { + return rb_ll2big(n); + } + else { + return ((VALUE)v) | RUBY_FIXNUM_FLAG; + } +#else if (FIXABLE(n)) return LONG2FIX(n); return rb_ll2big(n); +#endif } #endif /* HAVE_LONG_LONG */ |