diff mbox

[wide-int] Use __builtin_expect for length checks

Message ID 87txeu5h3x.fsf@talisman.default
State New
Headers show

Commit Message

Richard Sandiford Nov. 30, 2013, 10:17 a.m. UTC
Without profiling information, GCC tends to assume "x == 1" and
"x + y == 2" are likely false, so this patch adds some __builtin_expects.
(system.h has a dummy definition for compilers that don't support
__builtin_expect.)

Tested on x86_64-linux-gnu.  OK to install?

Thanks,
Richard

Comments

Richard Biener Nov. 30, 2013, noon UTC | #1
Richard Sandiford <rdsandiford@googlemail.com> wrote:
>Without profiling information, GCC tends to assume "x == 1" and
>"x + y == 2" are likely false, so this patch adds some
>__builtin_expects.
>(system.h has a dummy definition for compilers that don't support
>__builtin_expect.)
>
>Tested on x86_64-linux-gnu.  OK to install?

Ok.

Thanks,
Richard.

>Thanks,
>Richard
>
>
>Index: gcc/wide-int.h
>===================================================================
>--- gcc/wide-int.h	2013-11-30 09:40:32.710196218 +0000
>+++ gcc/wide-int.h	2013-11-30 10:07:06.567433289 +0000
>@@ -1675,7 +1675,7 @@ wi::eq_p (const T1 &x, const T2 &y)
>       while (++i != xi.len);
>       return true;
>     }
>-  if (yi.len == 1)
>+  if (__builtin_expect (yi.len == 1, true))
>     {
>       /* XI is only equal to YI if it too has a single HWI.  */
>       if (xi.len != 1)
>@@ -1751,7 +1751,7 @@ wi::ltu_p (const T1 &x, const T2 &y)
>/* Optimize the case of two HWIs.  The HWIs are implicitly
>sign-extended
>for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
>      values does not change the result.  */
>-  if (xi.len + yi.len == 2)
>+  if (__builtin_expect (xi.len + yi.len == 2, true))
>     {
>       unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
>       unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
>@@ -1922,7 +1922,7 @@ wi::cmpu (const T1 &x, const T2 &y)
>/* Optimize the case of two HWIs.  The HWIs are implicitly
>sign-extended
>for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
>      values does not change the result.  */
>-  if (xi.len + yi.len == 2)
>+  if (__builtin_expect (xi.len + yi.len == 2, true))
>     {
>       unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
>       unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
>@@ -2128,7 +2128,7 @@ wi::bit_and (const T1 &x, const T2 &y)
>   WIDE_INT_REF_FOR (T1) xi (x, precision);
>   WIDE_INT_REF_FOR (T2) yi (y, precision);
>   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
>-  if (xi.len + yi.len == 2)
>+  if (__builtin_expect (xi.len + yi.len == 2, true))
>     {
>       val[0] = xi.ulow () & yi.ulow ();
>       result.set_len (1, is_sign_extended);
>@@ -2149,7 +2149,7 @@ wi::bit_and_not (const T1 &x, const T2 &
>   WIDE_INT_REF_FOR (T1) xi (x, precision);
>   WIDE_INT_REF_FOR (T2) yi (y, precision);
>   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
>-  if (xi.len + yi.len == 2)
>+  if (__builtin_expect (xi.len + yi.len == 2, true))
>     {
>       val[0] = xi.ulow () & ~yi.ulow ();
>       result.set_len (1, is_sign_extended);
>@@ -2170,7 +2170,7 @@ wi::bit_or (const T1 &x, const T2 &y)
>   WIDE_INT_REF_FOR (T1) xi (x, precision);
>   WIDE_INT_REF_FOR (T2) yi (y, precision);
>   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
>-  if (xi.len + yi.len == 2)
>+  if (__builtin_expect (xi.len + yi.len == 2, true))
>     {
>       val[0] = xi.ulow () | yi.ulow ();
>       result.set_len (1, is_sign_extended);
>@@ -2191,7 +2191,7 @@ wi::bit_or_not (const T1 &x, const T2 &y
>   WIDE_INT_REF_FOR (T1) xi (x, precision);
>   WIDE_INT_REF_FOR (T2) yi (y, precision);
>   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
>-  if (xi.len + yi.len == 2)
>+  if (__builtin_expect (xi.len + yi.len == 2, true))
>     {
>       val[0] = xi.ulow () | ~yi.ulow ();
>       result.set_len (1, is_sign_extended);
>@@ -2212,7 +2212,7 @@ wi::bit_xor (const T1 &x, const T2 &y)
>   WIDE_INT_REF_FOR (T1) xi (x, precision);
>   WIDE_INT_REF_FOR (T2) yi (y, precision);
>   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
>-  if (xi.len + yi.len == 2)
>+  if (__builtin_expect (xi.len + yi.len == 2, true))
>     {
>       val[0] = xi.ulow () ^ yi.ulow ();
>       result.set_len (1, is_sign_extended);
>@@ -2248,7 +2248,7 @@ wi::add (const T1 &x, const T2 &y)
>      HOST_BITS_PER_WIDE_INT are relatively rare and there's not much
>      point handling them inline.  */
>   else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT)
>-	   && xi.len + yi.len == 2)
>+	   && __builtin_expect (xi.len + yi.len == 2, true))
>     {
>       unsigned HOST_WIDE_INT xl = xi.ulow ();
>       unsigned HOST_WIDE_INT yl = yi.ulow ();
>@@ -2323,7 +2323,7 @@ wi::sub (const T1 &x, const T2 &y)
>      HOST_BITS_PER_WIDE_INT are relatively rare and there's not much
>      point handling them inline.  */
>   else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT)
>-	   && xi.len + yi.len == 2)
>+	   && __builtin_expect (xi.len + yi.len == 2, true))
>     {
>       unsigned HOST_WIDE_INT xl = xi.ulow ();
>       unsigned HOST_WIDE_INT yl = yi.ulow ();
diff mbox

Patch

Index: gcc/wide-int.h
===================================================================
--- gcc/wide-int.h	2013-11-30 09:40:32.710196218 +0000
+++ gcc/wide-int.h	2013-11-30 10:07:06.567433289 +0000
@@ -1675,7 +1675,7 @@  wi::eq_p (const T1 &x, const T2 &y)
       while (++i != xi.len);
       return true;
     }
-  if (yi.len == 1)
+  if (__builtin_expect (yi.len == 1, true))
     {
       /* XI is only equal to YI if it too has a single HWI.  */
       if (xi.len != 1)
@@ -1751,7 +1751,7 @@  wi::ltu_p (const T1 &x, const T2 &y)
   /* Optimize the case of two HWIs.  The HWIs are implicitly sign-extended
      for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
      values does not change the result.  */
-  if (xi.len + yi.len == 2)
+  if (__builtin_expect (xi.len + yi.len == 2, true))
     {
       unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
       unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
@@ -1922,7 +1922,7 @@  wi::cmpu (const T1 &x, const T2 &y)
   /* Optimize the case of two HWIs.  The HWIs are implicitly sign-extended
      for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
      values does not change the result.  */
-  if (xi.len + yi.len == 2)
+  if (__builtin_expect (xi.len + yi.len == 2, true))
     {
       unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
       unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
@@ -2128,7 +2128,7 @@  wi::bit_and (const T1 &x, const T2 &y)
   WIDE_INT_REF_FOR (T1) xi (x, precision);
   WIDE_INT_REF_FOR (T2) yi (y, precision);
   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
-  if (xi.len + yi.len == 2)
+  if (__builtin_expect (xi.len + yi.len == 2, true))
     {
       val[0] = xi.ulow () & yi.ulow ();
       result.set_len (1, is_sign_extended);
@@ -2149,7 +2149,7 @@  wi::bit_and_not (const T1 &x, const T2 &
   WIDE_INT_REF_FOR (T1) xi (x, precision);
   WIDE_INT_REF_FOR (T2) yi (y, precision);
   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
-  if (xi.len + yi.len == 2)
+  if (__builtin_expect (xi.len + yi.len == 2, true))
     {
       val[0] = xi.ulow () & ~yi.ulow ();
       result.set_len (1, is_sign_extended);
@@ -2170,7 +2170,7 @@  wi::bit_or (const T1 &x, const T2 &y)
   WIDE_INT_REF_FOR (T1) xi (x, precision);
   WIDE_INT_REF_FOR (T2) yi (y, precision);
   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
-  if (xi.len + yi.len == 2)
+  if (__builtin_expect (xi.len + yi.len == 2, true))
     {
       val[0] = xi.ulow () | yi.ulow ();
       result.set_len (1, is_sign_extended);
@@ -2191,7 +2191,7 @@  wi::bit_or_not (const T1 &x, const T2 &y
   WIDE_INT_REF_FOR (T1) xi (x, precision);
   WIDE_INT_REF_FOR (T2) yi (y, precision);
   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
-  if (xi.len + yi.len == 2)
+  if (__builtin_expect (xi.len + yi.len == 2, true))
     {
       val[0] = xi.ulow () | ~yi.ulow ();
       result.set_len (1, is_sign_extended);
@@ -2212,7 +2212,7 @@  wi::bit_xor (const T1 &x, const T2 &y)
   WIDE_INT_REF_FOR (T1) xi (x, precision);
   WIDE_INT_REF_FOR (T2) yi (y, precision);
   bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended;
-  if (xi.len + yi.len == 2)
+  if (__builtin_expect (xi.len + yi.len == 2, true))
     {
       val[0] = xi.ulow () ^ yi.ulow ();
       result.set_len (1, is_sign_extended);
@@ -2248,7 +2248,7 @@  wi::add (const T1 &x, const T2 &y)
      HOST_BITS_PER_WIDE_INT are relatively rare and there's not much
      point handling them inline.  */
   else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT)
-	   && xi.len + yi.len == 2)
+	   && __builtin_expect (xi.len + yi.len == 2, true))
     {
       unsigned HOST_WIDE_INT xl = xi.ulow ();
       unsigned HOST_WIDE_INT yl = yi.ulow ();
@@ -2323,7 +2323,7 @@  wi::sub (const T1 &x, const T2 &y)
      HOST_BITS_PER_WIDE_INT are relatively rare and there's not much
      point handling them inline.  */
   else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT)
-	   && xi.len + yi.len == 2)
+	   && __builtin_expect (xi.len + yi.len == 2, true))
     {
       unsigned HOST_WIDE_INT xl = xi.ulow ();
       unsigned HOST_WIDE_INT yl = yi.ulow ();