On 17/01/15 13:06, Kugan wrote:
> Freeing a spare-bit to store wrapped attribute by going back to
> representing VR_ANTI_RANGE as [max + 1, min - 1] in SSA_NAME.
> 

Now that stage-1 is open, rebased it and regression tested on
x86-64-none-linux-gnu with no new regressions.

Is this OK for trunk?

Thanks,
Kugan


gcc/ChangeLog:

2015-04-22  Kugan Vivekanandarajah  <kug...@linaro.org>

        * tree-ssanames.c (set_range_info): Change range info representation
          and represent VR_ANTI_RANGE as [max + 1, min - 1].
        (get_range_info): Likewise.
        (set_nonzero_bits): Likewise.
        (duplicate_ssa_name_range_info): Likewise.
        * tree-ssanames.h (set_range_info): Change prototype.
        (get_range_info): Likewise.
        (set_nonzero_bits): Likewise.
        (duplicate_ssa_name_range_info): Likewise.
        * tree-vrp.c (remove_range_assertions): Use new representation.
        (vrp_finalize): Likewise.
        * tree-ssa-pre.c (insert_into_preds_of_block): Likewise.
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index d857d84..67e5351 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3205,7 +3205,6 @@ insert_into_preds_of_block (basic_block block, unsigned 
int exprnum,
          && !wi::neg_p (max, SIGNED))
        /* Just handle extension and sign-changes of all-positive ranges.  */
        set_range_info (temp,
-                       SSA_NAME_RANGE_TYPE (expr->u.nary->op[0]),
                        wide_int_storage::from (min, TYPE_PRECISION (type),
                                                TYPE_SIGN (type)),
                        wide_int_storage::from (max, TYPE_PRECISION (type),
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 9c39f65..744dc43 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -200,11 +200,10 @@ make_ssa_name_fn (struct function *fn, tree var, gimple 
stmt)
 /* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name NAME.  */
 
 void
-set_range_info (tree name, enum value_range_type range_type,
+set_range_info (tree name,
                const wide_int_ref &min, const wide_int_ref &max)
 {
   gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
-  gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
   range_info_def *ri = SSA_NAME_RANGE_INFO (name);
   unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));
 
@@ -219,16 +218,12 @@ set_range_info (tree name, enum value_range_type 
range_type,
       ri->set_nonzero_bits (wi::shwi (-1, precision));
     }
 
-  /* Record the range type.  */
-  if (SSA_NAME_RANGE_TYPE (name) != range_type)
-    SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
-
   /* Set the values.  */
   ri->set_min (min);
   ri->set_max (max);
 
   /* If it is a range, try to improve nonzero_bits from the min/max.  */
-  if (range_type == VR_RANGE)
+  if (wi::cmp (min, max, TYPE_SIGN (TREE_TYPE (name))) < 0)
     {
       wide_int xorv = ri->get_min () ^ ri->get_max ();
       if (xorv != 0)
@@ -248,6 +243,7 @@ get_range_info (const_tree name, wide_int *min, wide_int 
*max)
   gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
   gcc_assert (min && max);
   range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+  value_range_type range_type;
 
   /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
      with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
@@ -255,9 +251,22 @@ get_range_info (const_tree name, wide_int *min, wide_int 
*max)
              > 2 * HOST_BITS_PER_WIDE_INT))
     return VR_VARYING;
 
-  *min = ri->get_min ();
-  *max = ri->get_max ();
-  return SSA_NAME_RANGE_TYPE (name);
+   /* If max < min, it is VR_ANTI_RANGE.  */
+  if (wi::cmp (ri->get_max (), ri->get_min (), TYPE_SIGN (TREE_TYPE (name))) < 
0)
+    {
+      /* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1].  */
+      range_type = VR_ANTI_RANGE;
+      *min = wi::add (ri->get_max (), 1);
+      *max = wi::sub (ri->get_min (), 1);
+    }
+  else
+    {
+      /* Otherwise (when min <= max), it is VR_RANGE.  */
+      range_type = VR_RANGE;
+      *min = ri->get_min ();
+      *max = ri->get_max ();
+    }
+  return range_type;
 }
 
 /* Change non-zero bits bitmask of NAME.  */
@@ -267,7 +276,7 @@ set_nonzero_bits (tree name, const wide_int_ref &mask)
 {
   gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
   if (SSA_NAME_RANGE_INFO (name) == NULL)
-    set_range_info (name, VR_RANGE,
+    set_range_info (name,
                    TYPE_MIN_VALUE (TREE_TYPE (name)),
                    TYPE_MAX_VALUE (TREE_TYPE (name)));
   range_info_def *ri = SSA_NAME_RANGE_INFO (name);
@@ -495,7 +504,8 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def 
*ptr_info)
 /* Creates a duplicate of the range_info_def at RANGE_INFO of type
    RANGE_TYPE for use by the SSA name NAME.  */
 void
-duplicate_ssa_name_range_info (tree name, enum value_range_type range_type,
+duplicate_ssa_name_range_info (tree name,
+                              enum value_range_type range_type 
ATTRIBUTE_UNUSED,
                               struct range_info_def *range_info)
 {
   struct range_info_def *new_range_info;
@@ -513,8 +523,6 @@ duplicate_ssa_name_range_info (tree name, enum 
value_range_type range_type,
   new_range_info = static_cast<range_info_def *> (ggc_internal_alloc (size));
   memcpy (new_range_info, range_info, size);
 
-  gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
-  SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
   SSA_NAME_RANGE_INFO (name) = new_range_info;
 }
 
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index a7eeb8f..0d4b212 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -68,7 +68,7 @@ struct GTY ((variable_size)) range_info_def {
 enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
 
 /* Sets the value range to SSA.  */
-extern void set_range_info (tree, enum value_range_type, const wide_int_ref &,
+extern void set_range_info (tree, const wide_int_ref &,
                            const wide_int_ref &);
 /* Gets the value range from SSA.  */
 extern enum value_range_type get_range_info (const_tree, wide_int *,
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index e7ab23c..d823be9 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -6934,7 +6934,7 @@ remove_range_assertions (void)
                    && all_imm_uses_in_stmt_or_feed_cond (var, stmt,
                                                          single_pred (bb)))
                  {
-                   set_range_info (var, SSA_NAME_RANGE_TYPE (lhs),
+                   set_range_info (var,
                                    SSA_NAME_RANGE_INFO (lhs)->get_min (),
                                    SSA_NAME_RANGE_INFO (lhs)->get_max ());
                    maybe_set_nonzero_bits (bb, var);
@@ -10258,12 +10258,35 @@ vrp_finalize (void)
          || (vr_value[i]->type == VR_UNDEFINED))
        continue;
 
-       if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
-           && (TREE_CODE (vr_value[i]->max) == INTEGER_CST)
-           && (vr_value[i]->type == VR_RANGE
-               || vr_value[i]->type == VR_ANTI_RANGE))
-         set_range_info (name, vr_value[i]->type, vr_value[i]->min,
-                         vr_value[i]->max);
+      if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
+         && (TREE_CODE (vr_value[i]->max) == INTEGER_CST)
+         && (vr_value[i]->type == VR_RANGE
+             || vr_value[i]->type == VR_ANTI_RANGE))
+       {
+         if (vr_value[i]->type == VR_RANGE)
+          set_range_info (name, vr_value[i]->min, vr_value[i]->max);
+         else if (vr_value[i]->type == VR_ANTI_RANGE)
+           {
+             /* VR_ANTI_RANGE
+                ~[min, max] is encoded compactly as
+                [max + 1, min - 1] without additional attributes.
+                When min value > max value, we know that it is
+                VR_ANTI_RANGE; it is VR_RANGE otherwise.  */
+
+             if (TYPE_UNSIGNED (TREE_TYPE (name))
+                 && integer_zerop (vr_value[i]->min)
+                 && integer_zerop (vr_value[i]->max))
+               /* ~[0,0] anti-range is represented as range.  */
+               set_range_info (name,
+                               build_int_cst (TREE_TYPE (name), 1),
+                               TYPE_MAXVAL (TREE_TYPE (name)));
+             else
+               set_range_info (name,
+                               wi::add (vr_value[i]->max, 1),
+                               wi::sub (vr_value[i]->min, 1));
+           }
+       }
+
       }
 
   /* Free allocated memory.  */

Reply via email to