[前][次][番号順一覧][スレッド一覧]

ruby-changes:45720

From: naruse <ko1@a...>
Date: Tue, 7 Mar 2017 12:35:51 +0900 (JST)
Subject: [ruby-changes:45720] naruse:r57793 (trunk): Use ADD instead of MUL

naruse	2017-03-07 12:35:47 +0900 (Tue, 07 Mar 2017)

  New Revision: 57793

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57793

  Log:
    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.

  Modified files:
    trunk/bignum.c
    trunk/include/ruby/ruby.h
Index: bignum.c
===================================================================
--- bignum.c	(revision 57792)
+++ bignum.c	(revision 57793)
@@ -4436,18 +4436,8 @@ rb_ull2inum(unsigned LONG_LONG n) https://github.com/ruby/ruby/blob/trunk/bignum.c#L4436
 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 */
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 57792)
+++ include/ruby/ruby.h	(revision 57793)
@@ -359,7 +359,11 @@ rb_fix2ulong(VALUE x) https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L359
 #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) https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1511
 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) https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1518
     else {
 	return 1;
     }
-#endif
 }
 
 #if SIZEOF_INT < SIZEOF_LONG

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]