diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-03-07 03:35:47 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-03-07 03:35:47 +0000 |
commit | ac6f08df231d6f4972de75461a2a835c54fe1270 (patch) | |
tree | 0444aa77572bfb96a5b17e172486a8f8580eef0c /include | |
parent | d4c598c441ef408fbab3db544d30525b5bc9c1e9 (diff) | |
download | ruby-ac6f08df231d6f4972de75461a2a835c54fe1270.tar.gz |
Use ADD instead of MUL
* On recent CPUs, 2-operand MUL's latency is 3 cycle but ADD is 1 cycle.
* clang Optimizes `MUL rax,2` into `ADD rax,rax` but gcc7 doesn't.
* LONG2FIX is compiled into `lea r14,[r15+r15*1+0x1]`; this is 1cycle
and run in parallel if the branch prediction is correct.
* Note that old (RB_POSFIXABLE(f) && RB_NEGFIXABLE(f)) is usually uses
following instructions.
* movabs rax,0x4000000000000000
* add rax,rdi
* js
It needs large immediate and Macro-Fusion is not applied.
ADD and JO is much smaller though it is also Macro-Fusion unfriendly.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57793 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'include')
-rw-r--r-- | include/ruby/ruby.h | 17 |
1 files changed, 5 insertions, 12 deletions
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 0cd88fb002..1cc9937acb 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -359,7 +359,11 @@ rb_fix2ulong(VALUE x) #define RB_FIXNUM_P(f) (((int)(SIGNED_VALUE)(f))&RUBY_FIXNUM_FLAG) #define RB_POSFIXABLE(f) ((f) < RUBY_FIXNUM_MAX+1) #define RB_NEGFIXABLE(f) ((f) >= RUBY_FIXNUM_MIN) -#define RB_FIXABLE(f) (RB_POSFIXABLE(f) && RB_NEGFIXABLE(f)) +#if defined HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW +# define RB_FIXABLE(f) ({SIGNED_VALUE a=(f),c; !__builtin_add_overflow(a, a, &c);}) +#else +# define RB_FIXABLE(f) (RB_POSFIXABLE(f) && RB_NEGFIXABLE(f)) +#endif #define FIX2LONG(x) RB_FIX2LONG(x) #define FIX2ULONG(x) RB_FIX2ULONG(x) #define FIXNUM_P(f) RB_FIXNUM_P(f) @@ -1507,16 +1511,6 @@ rb_integer_type_p(VALUE obj) static inline int rb_long2fix_overflow(long l, VALUE *ptr) { -#ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW - SIGNED_VALUE v; - if (__builtin_mul_overflow(l, 2, &v)) { - return 1; - } - else { - *ptr = ((VALUE)v) | RUBY_FIXNUM_FLAG; - return 0; - } -#else if (RB_FIXABLE(l)) { *ptr = RB_LONG2FIX(l); return 0; @@ -1524,7 +1518,6 @@ rb_long2fix_overflow(long l, VALUE *ptr) else { return 1; } -#endif } #if SIZEOF_INT < SIZEOF_LONG |