Use poly_int tree accessors
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 30 May 2018 06:31:47 +0000 (06:31 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 May 2018 06:31:47 +0000 (06:31 +0000)
This patch generalises various places that used hwi tree accessors so
that they can handle poly_ints instead.  In many cases these changes
are by inspection rather than because something had shown them to be
necessary.

I think the alias.c part is a minor bug fix: previously we used
fits_uhwi_p for a signed HOST_WIDE_INT (which the caller does
treat as signed rather than unsigned).  We also checked whether
each individual offset overflowed but didn't check whether the
sum did.

2018-05-30  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* alias.c (adjust_offset_for_component_ref): Use poly_int_tree_p
and wi::to_poly_offset.  Add the current offset and then check
whether the sum fits, rather than using an unchecked addition of
a checked term.  Check for a shwi rather than a uhwi.
* expr.c (get_bit_range): Use tree_to_poly_uint64.
(store_constructor): Use poly_int_tree_p.
(expand_expr_real_1): Likewise.
* function.c (assign_temp): Likewise.
* fold-const.c (const_binop): Use poly_int_tree_p and
wi::to_poly_offset.
(fold_indirect_ref_1): Likewise.  Use multiple_p to attempt an exact
division.
* ipa-icf-gimple.c (func_checker::compare_operand): Use
to_poly_offset for MEM offsets.
* ipa-icf.c (sem_variable::equals): Likewise.
* stor-layout.c (compute_record_mode): Use poly_int_tree_p.
* tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use
wi::to_poly_offset for BIT_FIELD_REF offsets.
(vn_reference_maybe_forwprop_address): Use poly_int_tree_p and
wi::to_poly_offset.
* var-tracking.c (emit_note_insn_var_location): Use
tree_to_poly_uint64.

From-SVN: r260914

gcc/ChangeLog
gcc/alias.c
gcc/expr.c
gcc/fold-const.c
gcc/function.c
gcc/ipa-icf-gimple.c
gcc/ipa-icf.c
gcc/stor-layout.c
gcc/tree-ssa-sccvn.c
gcc/var-tracking.c

index c9d89aa17546861d3325746491c0903d1a9018b6..51958e8c3b5c8b4eb41e87fc43aca4597a50945c 100644 (file)
@@ -1,3 +1,28 @@
+2018-05-30  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * alias.c (adjust_offset_for_component_ref): Use poly_int_tree_p
+       and wi::to_poly_offset.  Add the current offset and then check
+       whether the sum fits, rather than using an unchecked addition of
+       a checked term.  Check for a shwi rather than a uhwi.
+       * expr.c (get_bit_range): Use tree_to_poly_uint64.
+       (store_constructor): Use poly_int_tree_p.
+       (expand_expr_real_1): Likewise.
+       * function.c (assign_temp): Likewise.
+       * fold-const.c (const_binop): Use poly_int_tree_p and
+       wi::to_poly_offset.
+       (fold_indirect_ref_1): Likewise.  Use multiple_p to attempt an exact
+       division.
+       * ipa-icf-gimple.c (func_checker::compare_operand): Use
+       to_poly_offset for MEM offsets.
+       * ipa-icf.c (sem_variable::equals): Likewise.
+       * stor-layout.c (compute_record_mode): Use poly_int_tree_p.
+       * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use
+       wi::to_poly_offset for BIT_FIELD_REF offsets.
+       (vn_reference_maybe_forwprop_address): Use poly_int_tree_p and
+       wi::to_poly_offset.
+       * var-tracking.c (emit_note_insn_var_location): Use
+       tree_to_poly_uint64.
+
 2018-05-29  Jim Wilson  <jimw@sifive.com>
 
        * config/riscv/riscv.c (riscv_interrupt_type): Fix comment typo.
index 74032f8503b75eaf4c9039d699764e5894f8cd74..40c74a07a4654152c488d92e73e8f91605dead82 100644 (file)
@@ -2698,22 +2698,22 @@ adjust_offset_for_component_ref (tree x, bool *known_p,
     {
       tree xoffset = component_ref_field_offset (x);
       tree field = TREE_OPERAND (x, 1);
-      if (TREE_CODE (xoffset) != INTEGER_CST)
+      if (!poly_int_tree_p (xoffset))
        {
          *known_p = false;
          return;
        }
 
-      offset_int woffset
-       = (wi::to_offset (xoffset)
+      poly_offset_int woffset
+       = (wi::to_poly_offset (xoffset)
           + (wi::to_offset (DECL_FIELD_BIT_OFFSET (field))
-             >> LOG2_BITS_PER_UNIT));
-      if (!wi::fits_uhwi_p (woffset))
+             >> LOG2_BITS_PER_UNIT)
+          + *offset);
+      if (!woffset.to_shwi (offset))
        {
          *known_p = false;
          return;
        }
-      *offset += woffset.to_uhwi ();
 
       x = TREE_OPERAND (x, 0);
     }
index 51fbc326000773470d150d6a775f16aa1e2c37ed..1fa32275fdfe807e4e320eaabadb394ca931df28 100644 (file)
@@ -4913,7 +4913,7 @@ get_bit_range (poly_uint64_pod *bitstart, poly_uint64_pod *bitend, tree exp,
   else
     *bitstart = *bitpos - bitoffset;
 
-  *bitend = *bitstart + tree_to_uhwi (DECL_SIZE (repr)) - 1;
+  *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1;
 }
 
 /* Returns true if ADDR is an ADDR_EXPR of a DECL that does not reside
@@ -6521,12 +6521,10 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
              continue;
 
            mode = TYPE_MODE (elttype);
-           if (mode == BLKmode)
-             bitsize = (tree_fits_uhwi_p (TYPE_SIZE (elttype))
-                        ? tree_to_uhwi (TYPE_SIZE (elttype))
-                        : -1);
-           else
+           if (mode != BLKmode)
              bitsize = GET_MODE_BITSIZE (mode);
+           else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize))
+             bitsize = -1;
 
            if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
              {
@@ -10249,11 +10247,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
          {
            poly_int64 offset = mem_ref_offset (exp).force_shwi ();
            base = TREE_OPERAND (base, 0);
+           poly_uint64 type_size;
            if (known_eq (offset, 0)
                && !reverse
-               && tree_fits_uhwi_p (TYPE_SIZE (type))
-               && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)),
-                            tree_to_uhwi (TYPE_SIZE (type))))
+               && poly_int_tree_p (TYPE_SIZE (type), &type_size)
+               && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
              return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
                                  target, tmode, modifier);
            if (TYPE_MODE (type) == BLKmode)
index 3258aad44be69e279f88814a15242e5c82e80e91..6f80f1b1d695fd6920ddab46ce8ce8db47bb9ed3 100644 (file)
@@ -1611,10 +1611,10 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
       return NULL_TREE;
 
     case POINTER_DIFF_EXPR:
-      if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST)
+      if (poly_int_tree_p (arg1) && poly_int_tree_p (arg2))
        {
-         offset_int res = wi::sub (wi::to_offset (arg1),
-                                   wi::to_offset (arg2));
+         poly_offset_int res = (wi::to_poly_offset (arg1)
+                                - wi::to_poly_offset (arg2));
          return force_fit_type (type, res, 1,
                                 TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
        }
@@ -14202,13 +14202,12 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
              tree min_val = size_zero_node;
              if (type_domain && TYPE_MIN_VALUE (type_domain))
                min_val = TYPE_MIN_VALUE (type_domain);
-             offset_int off = wi::to_offset (op01);
-             offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type));
-             offset_int remainder;
-             off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder);
-             if (remainder == 0 && TREE_CODE (min_val) == INTEGER_CST)
+             poly_uint64 type_size, index;
+             if (poly_int_tree_p (min_val)
+                 && poly_int_tree_p (TYPE_SIZE_UNIT (type), &type_size)
+                 && multiple_p (const_op01, type_size, &index))
                {
-                 off = off + wi::to_offset (min_val);
+                 poly_offset_int off = index + wi::to_poly_offset (min_val);
                  op01 = wide_int_to_tree (sizetype, off);
                  return build4_loc (loc, ARRAY_REF, type, op00, op01,
                                     NULL_TREE, NULL_TREE);
index 61515e38e47741d8f6551414acf369caea637810..6b9fd597d41e6f60f972fba096cab3bd7db1edd2 100644 (file)
@@ -978,25 +978,26 @@ assign_temp (tree type_or_decl, int memory_required,
 
   if (mode == BLKmode || memory_required)
     {
-      HOST_WIDE_INT size = int_size_in_bytes (type);
+      poly_int64 size;
       rtx tmp;
 
-      /* Zero sized arrays are GNU C extension.  Set size to 1 to avoid
-        problems with allocating the stack space.  */
-      if (size == 0)
-       size = 1;
-
       /* Unfortunately, we don't yet know how to allocate variable-sized
         temporaries.  However, sometimes we can find a fixed upper limit on
         the size, so try that instead.  */
-      else if (size == -1)
+      if (!poly_int_tree_p (TYPE_SIZE_UNIT (type), &size))
        size = max_int_size_in_bytes (type);
 
+      /* Zero sized arrays are a GNU C extension.  Set size to 1 to avoid
+        problems with allocating the stack space.  */
+      if (known_eq (size, 0))
+       size = 1;
+
       /* The size of the temporary may be too large to fit into an integer.  */
       /* ??? Not sure this should happen except for user silliness, so limit
         this to things that aren't compiler-generated temporaries.  The
         rest of the time we'll die in assign_stack_temp_for_type.  */
-      if (decl && size == -1
+      if (decl
+         && !known_size_p (size)
          && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
        {
          error ("size of variable %q+D is too large", decl);
index 161080c77bc72785cd0ae0724839630ccabd2323..6a5d1e969418602852a1f5110f1cf18501d414ff 100644 (file)
@@ -463,7 +463,7 @@ func_checker::compare_operand (tree t1, tree t2)
          return return_false_with_msg ("");
 
        /* Type of the offset on MEM_REF does not matter.  */
-       return wi::to_offset  (y1) == wi::to_offset  (y2);
+       return known_eq (wi::to_poly_offset (y1), wi::to_poly_offset (y2));
       }
     case COMPONENT_REF:
       {
index 37e63fc2ba8a72ab138671d5e239aac9cfdfef37..5a1e13560d6be5c391bbf60e1cec4b276cef5124 100644 (file)
@@ -1983,8 +1983,8 @@ sem_variable::equals (tree t1, tree t2)
 
        /* Type of the offset on MEM_REF does not matter.  */
        return return_with_debug (sem_variable::equals (x1, x2)
-                                 && wi::to_offset  (y1)
-                                    == wi::to_offset  (y2));
+                                 && known_eq (wi::to_poly_offset (y1),
+                                              wi::to_poly_offset (y2)));
       }
     case ADDR_EXPR:
     case FDESC_EXPR:
index 81f75a5eb72b22b5e77e0affb804e6c820fe69ca..dd08165e6061c1e190b29bd269ef2a3ab5df12b6 100644 (file)
@@ -1838,9 +1838,11 @@ compute_record_mode (tree type)
   /* If we only have one real field; use its mode if that mode's size
      matches the type's size.  This only applies to RECORD_TYPE.  This
      does not apply to unions.  */
-  if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
-      && tree_fits_uhwi_p (TYPE_SIZE (type))
-      && known_eq (GET_MODE_BITSIZE (mode), tree_to_uhwi (TYPE_SIZE (type))))
+  poly_uint64 type_size;
+  if (TREE_CODE (type) == RECORD_TYPE
+      && mode != VOIDmode
+      && poly_int_tree_p (TYPE_SIZE (type), &type_size)
+      && known_eq (GET_MODE_BITSIZE (mode), type_size))
     ;
   else
     mode = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1).else_blk ();
index 62015fda9293451fdd5b4b72aa04c64fe2bc8baa..4e946ba7bafe754d815ff72e79001c65b0e004dd 100644 (file)
@@ -999,7 +999,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
 
        /* And now the usual component-reference style ops.  */
        case BIT_FIELD_REF:
-         offset += wi::to_offset (op->op1);
+         offset += wi::to_poly_offset (op->op1);
          break;
 
        case COMPONENT_REF:
@@ -1265,10 +1265,10 @@ vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
       ptroff = gimple_assign_rhs2 (def_stmt);
       if (TREE_CODE (ptr) != SSA_NAME
          || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
-         || TREE_CODE (ptroff) != INTEGER_CST)
+         || !poly_int_tree_p (ptroff))
        return false;
 
-      off += wi::to_offset (ptroff);
+      off += wi::to_poly_offset (ptroff);
       op->op0 = ptr;
     }
 
index 2b21da3dfce2b12626859fcc871b2fd762d21b6b..16e1ea8f9976b0b0cbad5e97b53fd51a66daa491 100644 (file)
@@ -8665,7 +8665,6 @@ emit_note_insn_var_location (variable **varp, emit_note_data *data)
   bool complete;
   enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
   HOST_WIDE_INT last_limit;
-  tree type_size_unit;
   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
   rtx loc[MAX_VAR_PARTS];
   tree decl;
@@ -8816,8 +8815,9 @@ emit_note_insn_var_location (variable **varp, emit_note_data *data)
        }
       ++n_var_parts;
     }
-  type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
-  if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
+  poly_uint64 type_size_unit
+    = tree_to_poly_uint64 (TYPE_SIZE_UNIT (TREE_TYPE (decl)));
+  if (maybe_lt (poly_uint64 (last_limit), type_size_unit))
     complete = false;
 
   if (! flag_var_tracking_uninit)