like the add/sub patch, enhance the comment so that it says that it is designed to hit the widestint and offset int common cases.

kenny
On 11/28/2013 12:34 PM, Richard Sandiford wrote:
As Richi asked, this patch makes cmps use the same shortcuts as lts_p.
It also makes cmpu use the shortcut that I justed added to ltu_p.

On that same fold-const.ii testcase, this reduces the number of cmps_large
calls from 66924 to 916.  It reduces the number of cmpu_large calls from
3462 to 4.

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

Thanks,
Richard


Index: gcc/wide-int.h
===================================================================
--- gcc/wide-int.h      2001-01-01 00:00:00.000000000 +0000
+++ gcc/wide-int.h      2013-11-28 16:08:22.527681077 +0000
@@ -1858,17 +1858,31 @@ wi::cmps (const T1 &x, const T2 &y)
    unsigned int precision = get_binary_precision (x, y);
    WIDE_INT_REF_FOR (T1) xi (x, precision);
    WIDE_INT_REF_FOR (T2) yi (y, precision);
-  if (precision <= HOST_BITS_PER_WIDE_INT)
+  if (wi::fits_shwi_p (yi))
      {
-      HOST_WIDE_INT xl = xi.to_shwi ();
-      HOST_WIDE_INT yl = yi.to_shwi ();
-      if (xl < yl)
+      /* Special case for comparisons with 0.  */
+      if (STATIC_CONSTANT_P (yi.val[0] == 0))
+       return neg_p (xi) ? -1 : !(xi.len == 1 && xi.val[0] == 0);
+      /* If x fits into a signed HWI, we can compare directly.  */
+      if (wi::fits_shwi_p (xi))
+       {
+         HOST_WIDE_INT xl = xi.to_shwi ();
+         HOST_WIDE_INT yl = yi.to_shwi ();
+         return xl < yl ? -1 : xl > yl;
+       }
+      /* If x doesn't fit and is negative, then it must be more
+        negative than any signed HWI, and hence smaller than y.  */
+      if (neg_p (xi))
        return -1;
-      else if (xl > yl)
-       return 1;
-      else
-       return 0;
+      /* If x is positive, then it must be larger than any signed HWI,
+        and hence greater than y.  */
+      return 1;
      }
+  /* Optimize the opposite case, if it can be detected at compile time.  */
+  if (STATIC_CONSTANT_P (xi.len == 1))
+    /* If YI is negative it is lower than the least HWI.
+       If YI is positive it is greater than the greatest HWI.  */
+    return neg_p (yi) ? 1 : -1;
    return cmps_large (xi.val, xi.len, precision, yi.val, yi.len);
  }
@@ -1881,16 +1895,35 @@ wi::cmpu (const T1 &x, const T2 &y)
    unsigned int precision = get_binary_precision (x, y);
    WIDE_INT_REF_FOR (T1) xi (x, precision);
    WIDE_INT_REF_FOR (T2) yi (y, precision);
-  if (precision <= HOST_BITS_PER_WIDE_INT)
+  /* Optimize comparisons with constants.  */
+  if (STATIC_CONSTANT_P (yi.len == 1 && yi.val[0] >= 0))
      {
+      /* If XI doesn't fit in a HWI then it must be larger than YI.  */
+      if (xi.len != 1)
+       return 1;
+      /* Otherwise compare directly.  */
        unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
-      unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
-      if (xl < yl)
+      unsigned HOST_WIDE_INT yl = yi.val[0];
+      return xl < yl ? -1 : xl > yl;
+    }
+  if (STATIC_CONSTANT_P (xi.len == 1 && xi.val[0] >= 0))
+    {
+      /* If YI doesn't fit in a HWI then it must be larger than XI.  */
+      if (yi.len != 1)
        return -1;
-      else if (xl == yl)
-       return 0;
-      else
-       return 1;
+      /* Otherwise compare directly.  */
+      unsigned HOST_WIDE_INT xl = xi.val[0];
+      unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
+      return xl < yl ? -1 : xl > yl;
+    }
+  /* 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)
+    {
+      unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
+      unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
+      return xl < yl ? -1 : xl > yl;
      }
    return cmpu_large (xi.val, xi.len, precision, yi.val, yi.len);
  }


Reply via email to