Jeff Law <l...@redhat.com> writes:
> On 01/09/2018 11:39 AM, Richard Sandiford wrote:
>> This patch generalises various places that used hwi tree accessors
>> so that they can handle poly_ints instead.  Earlier patches did
>> this while updating interfaces; this patch just mops up some
>> left-over pieces that weren't necessary to make things compile,
>> but that still make sense.
>> 
>> 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.
>> 
>> Sorry for not posting this earlier.  I kept holding it back in case
>> more examples showed up.
>> 
>> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
>> Also tested by comparing the before-and-after assembly output for at
>> least one target per CPU directory.  OK to install?
>> 
>> Richard
>> 
>> 
>> 2018-01-09  Richard Sandiford  <richard.sandif...@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 known_in_range_p to test
>>      for an in-range vector access and multiple_p to attempt an exact
>>      division.
>>      * gimplify.c (gimple_add_tmp_var_fn): Use tree_fits_poly_uint64_p.
>>      (gimple_add_tmp_var): Likewise.
>>      * 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-vectorizer.c (get_vec_alignment_for_array_type): Likewise.
>>      * tree-predcom.c (aff_combination_dr_offset): Use wi::to_poly_widest
>>      rather than wi::to_widest for DR_INITs.
>>      * 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.
>>      * tree-vect-data-refs.c (vect_find_same_alignment_drs): Use
>>      wi::to_poly_offset for DR_INIT.
>>      (vect_analyze_data_ref_accesses): Require both DR_INITs to be
>>      INTEGER_CSTs.
>>      (vect_analyze_group_access_1): Note that here.
>>      * var-tracking.c (emit_note_insn_var_location): Use
>>      tree_to_poly_uint64.
> OK.  If minor edits are necessary to deal changes since this was
> originally posted, consider those pre-approved.

Thanks Jeff!  Finally got round to updating and retesting this.
Committed as r260914.

Richard


2018-05-30  Richard Sandiford  <richard.sandif...@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.

Index: gcc/alias.c
===================================================================
--- gcc/alias.c 2018-04-10 11:26:52.500490858 +0100
+++ gcc/alias.c 2018-05-30 07:26:50.931554833 +0100
@@ -2698,22 +2698,22 @@ adjust_offset_for_component_ref (tree x,
     {
       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: gcc/expr.c
===================================================================
--- gcc/expr.c  2018-05-18 09:26:37.721714880 +0100
+++ gcc/expr.c  2018-05-30 07:26:50.933554808 +0100
@@ -4913,7 +4913,7 @@ get_bit_range (poly_uint64_pod *bitstart
   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,
              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)
              {
@@ -10235,11 +10233,11 @@ expand_expr_real_1 (tree exp, rtx target
          {
            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: gcc/function.c
===================================================================
--- gcc/function.c      2018-03-24 10:52:14.276582048 +0000
+++ gcc/function.c      2018-05-30 07:26:50.935554783 +0100
@@ -978,25 +978,26 @@ assign_temp (tree type_or_decl, int memo
 
   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: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    2018-05-30 07:24:51.607241042 +0100
+++ gcc/fold-const.c    2018-05-30 07:26:50.934554795 +0100
@@ -1611,10 +1611,10 @@ const_binop (enum tree_code code, tree t
       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));
        }
@@ -14193,13 +14193,12 @@ fold_indirect_ref_1 (location_t loc, tre
              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: gcc/ipa-icf-gimple.c
===================================================================
--- gcc/ipa-icf-gimple.c        2018-01-12 16:56:29.267928000 +0000
+++ gcc/ipa-icf-gimple.c        2018-05-30 07:26:50.935554783 +0100
@@ -463,7 +463,7 @@ func_checker::compare_operand (tree t1,
          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: gcc/ipa-icf.c
===================================================================
--- gcc/ipa-icf.c       2018-05-22 13:22:01.883333074 +0100
+++ gcc/ipa-icf.c       2018-05-30 07:26:50.935554783 +0100
@@ -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: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c   2018-03-01 08:20:43.845526342 +0000
+++ gcc/stor-layout.c   2018-05-30 07:26:50.936554770 +0100
@@ -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: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        2018-05-30 07:24:51.894236549 +0100
+++ gcc/tree-ssa-sccvn.c        2018-05-30 07:26:50.936554770 +0100
@@ -999,7 +999,7 @@ ao_ref_init_from_vn_reference (ao_ref *r
 
        /* 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
       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: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c  2018-05-01 19:31:03.074312721 +0100
+++ gcc/var-tracking.c  2018-05-30 07:26:50.937554757 +0100
@@ -8665,7 +8665,6 @@ emit_note_insn_var_location (variable **
   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 **
        }
       ++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)

Reply via email to