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

ruby-changes:43441

From: naruse <ko1@a...>
Date: Tue, 28 Jun 2016 03:30:25 +0900 (JST)
Subject: [ruby-changes:43441] naruse:r55515 (trunk): * insns.def (opt_plus): use `- 1` instead of `& (~1)` to allow

naruse	2016-06-28 03:30:12 +0900 (Tue, 28 Jun 2016)

  New Revision: 55515

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

  Log:
    * insns.def (opt_plus): use `- 1` instead of `& (~1)` to allow
      compilers to use x86 LEA instruction (3 operand).
      Even if 3 operand LEA's latency is 3 cycle after SandyBridge,
      it reduces code size and can be faster because of super scalar.
    
    * insns.def (opt_plus): calculate and use rb_int2big.
      On positive Fixnum overflow, `recv - 1 + obj` doesn't carry
      because recv's msb and obj's msb are 0, and resulted msb is 1.
      Therefore simply rshift and cast as signed long works fine.
      On negative Fixnum overflow, it will carry because both arguments'
      msb are 1, and resulted msb is also 1.
      In this case it needs to restore carried sign bit after rshift.

  Modified files:
    trunk/ChangeLog
    trunk/insns.def
Index: insns.def
===================================================================
--- insns.def	(revision 55514)
+++ insns.def	(revision 55515)
@@ -1381,18 +1381,13 @@ opt_plus https://github.com/ruby/ruby/blob/trunk/insns.def#L1381
 	BASIC_OP_UNREDEFINED_P(BOP_PLUS,INTEGER_REDEFINED_OP_FLAG)) {
 	/* fixnum + fixnum */
 #ifndef LONG_LONG_VALUE
-	val = (recv + (obj & (~1)));
-	if ((~(recv ^ obj) & (recv ^ val)) &
-	    ((VALUE)0x01 << ((sizeof(VALUE) * CHAR_BIT) - 1))) {
-	    val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
-			      rb_int2big(FIX2LONG(obj)));
-	}
+        VALUE msb = (VALUE)1 << ((sizeof(VALUE) * CHAR_BIT) - 1);
+        val = recv - 1 + obj;
+        if ((~(recv ^ obj) & (recv ^ val)) & msb) {
+            val = rb_int2big((SIGNED_VALUE)((val>>1) | (recv & msb)));
+        }
 #else
-	long a, b, c;
-	a = FIX2LONG(recv);
-	b = FIX2LONG(obj);
-	c = a + b;
-	val = LONG2NUM(c);
+	val = LONG2NUM(FIX2LONG(recv) + FIX2LONG(obj));
 #endif
     }
     else if (FLONUM_2_P(recv, obj) &&
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55514)
+++ ChangeLog	(revision 55515)
@@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Jun 28 02:41:32 2016  NARUSE, Yui  <naruse@r...>
+
+	* insns.def (opt_plus): use `- 1` instead of `& (~1)` to allow
+	  compilers to use x86 LEA instruction (3 operand).
+	  Even if 3 operand LEA's latency is 3 cycle after SandyBridge,
+	  it reduces code size and can be faster because of super scalar.
+
+	* insns.def (opt_plus): calculate and use rb_int2big.
+	  On positive Fixnum overflow, `recv - 1 + obj` doesn't carry
+	  because recv's msb and obj's msb are 0, and resulted msb is 1.
+	  Therefore simply rshift and cast as signed long works fine.
+	  On negative Fixnum overflow, it will carry because both arguments'
+	  msb are 1, and resulted msb is also 1.
+	  In this case it needs to restore carried sign bit after rshift.
+
 Mon Jun 27 16:58:32 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/fileutils.rb (FileUtils#install): accecpt symbolic mode, as

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

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