double-int.h (rshift): New overload.
authorRichard Biener <rguenther@suse.de>
Tue, 7 May 2013 11:26:58 +0000 (11:26 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 7 May 2013 11:26:58 +0000 (11:26 +0000)
2013-05-07  Richard Biener  <rguenther@suse.de>

* double-int.h (rshift): New overload.
* double-int.c (rshift): New function.
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Optimize.
(create_reference_ops_from_ref): Remove.
(vn_reference_insert): Use shared ops for constructing the
reference and copy it.

From-SVN: r198676

gcc/ChangeLog
gcc/double-int.c
gcc/double-int.h
gcc/tree-ssa-sccvn.c

index 879c0244054042b1276e11ac282efbb529bae601..0dc66003fb4f3f2b56186423bc92defb174ce762 100644 (file)
@@ -1,3 +1,12 @@
+2013-05-07  Richard Biener  <rguenther@suse.de>
+
+       * double-int.h (rshift): New overload.
+       * double-int.c (rshift): New function.
+       * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Optimize.
+       (create_reference_ops_from_ref): Remove.
+       (vn_reference_insert): Use shared ops for constructing the
+       reference and copy it.
+
 2013-05-07  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/57190
index b098f57b65cde9b3675b03b301df8e1327d85a65..fe3c096619ab0acce595955d74207279bd33b1dc 100644 (file)
@@ -1116,6 +1116,39 @@ double_int::lshift (HOST_WIDE_INT count) const
   return ret;
 }
 
+/* Shift A right by COUNT places.  */
+
+double_int
+double_int::rshift (HOST_WIDE_INT count) const
+{
+  double_int ret;
+
+  gcc_checking_assert (count >= 0);
+
+  if (count >= HOST_BITS_PER_DOUBLE_INT)
+    {
+      /* Shifting by the host word size is undefined according to the
+        ANSI standard, so we must handle this as a special case.  */
+      ret.high = 0;
+      ret.low = 0;
+    }
+  else if (count >= HOST_BITS_PER_WIDE_INT)
+    {
+      ret.high = 0;
+      ret.low
+       = (unsigned HOST_WIDE_INT) (high >> (count - HOST_BITS_PER_WIDE_INT));
+    }
+  else
+    {
+      ret.high = high >> count;
+      ret.low = ((low >> count)
+                | ((unsigned HOST_WIDE_INT) high
+                   << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
+    }
+
+  return ret;
+}
+
 /* Shift A left by COUNT places keeping only PREC bits of result.  Shift
    right if COUNT is negative.  ARITH true specifies arithmetic shifting;
    otherwise use logical shift.  */
index 39929d2b5bf1ddbf2fed1e257703387eb9f7c77e..8e709e6d415eb0b3367b26fd7dca0c65d780e174 100644 (file)
@@ -130,6 +130,7 @@ struct double_int
 
   double_int lshift (HOST_WIDE_INT count) const;
   double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
+  double_int rshift (HOST_WIDE_INT count) const;
   double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
   double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
   double_int arshift (HOST_WIDE_INT count, unsigned int prec) const;
index 07bfdcccb81beb56075db9e133cc6360f38d6bd4..49d61b0c239647f4ffcd598f1078f0cb5955c1fc 100644 (file)
@@ -728,6 +728,8 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
     {
       vn_reference_op_s temp;
 
+      result->reserve (3);
+
       memset (&temp, 0, sizeof (temp));
       temp.type = TREE_TYPE (ref);
       temp.opcode = TREE_CODE (ref);
@@ -735,21 +737,21 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
       temp.op1 = TMR_STEP (ref);
       temp.op2 = TMR_OFFSET (ref);
       temp.off = -1;
-      result->safe_push (temp);
+      result->quick_push (temp);
 
       memset (&temp, 0, sizeof (temp));
       temp.type = NULL_TREE;
       temp.opcode = ERROR_MARK;
       temp.op0 = TMR_INDEX2 (ref);
       temp.off = -1;
-      result->safe_push (temp);
+      result->quick_push (temp);
 
       memset (&temp, 0, sizeof (temp));
       temp.type = NULL_TREE;
       temp.opcode = TREE_CODE (TMR_BASE (ref));
       temp.op0 = TMR_BASE (ref);
       temp.off = -1;
-      result->safe_push (temp);
+      result->quick_push (temp);
       return;
     }
 
@@ -802,9 +804,8 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
                    double_int off
                      = tree_to_double_int (this_offset)
                        + tree_to_double_int (bit_offset)
-                         .arshift (BITS_PER_UNIT == 8
-                                   ? 3 : exact_log2 (BITS_PER_UNIT),
-                                   HOST_BITS_PER_DOUBLE_INT);
+                       .rshift (BITS_PER_UNIT == 8
+                                  ? 3 : exact_log2 (BITS_PER_UNIT));
                    if (off.fits_shwi ())
                      temp.off = off.low;
                  }
@@ -846,7 +847,7 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
          temp.off = 0;
          result->safe_push (temp);
          temp.opcode = ADDR_EXPR;
-         temp.op0 = build_fold_addr_expr (ref);
+         temp.op0 = build1 (ADDR_EXPR, TREE_TYPE (temp.op0), ref);
          temp.type = TREE_TYPE (temp.op0);
          temp.off = -1;
          break;
@@ -1114,18 +1115,6 @@ copy_reference_ops_from_call (gimple call,
     }
 }
 
-/* Create a vector of vn_reference_op_s structures from REF, a
-   REFERENCE_CLASS_P tree.  The vector is not shared. */
-
-static vec<vn_reference_op_s> 
-create_reference_ops_from_ref (tree ref)
-{
-  vec<vn_reference_op_s> result = vNULL;
-
-  copy_reference_ops_from_ref (ref, &result);
-  return result;
-}
-
 /* Create a vector of vn_reference_op_s structures from CALL, a
    call statement.  The vector is not shared.  */
 
@@ -2096,6 +2085,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
 {
   vn_reference_s **slot;
   vn_reference_t vr1;
+  bool tem;
 
   vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
   if (TREE_CODE (result) == SSA_NAME)
@@ -2103,7 +2093,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
   else
     vr1->value_id = get_or_alloc_constant_value_id (result);
   vr1->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
-  vr1->operands = valueize_refs (create_reference_ops_from_ref (op));
+  vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy ();
   vr1->type = TREE_TYPE (op);
   vr1->set = get_alias_set (op);
   vr1->hashcode = vn_reference_compute_hash (vr1);