This patch makes expand_debug_expr track polynomial memory offsets.
It simplifies the handling of the case in which the reference is not
to the first byte of the base, which seemed non-trivial enough to
make it worth splitting out as a separate patch.


2017-10-23  Richard Sandiford  <richard.sandif...@linaro.org>
            Alan Hayward  <alan.hayw...@arm.com>
            David Sherwood  <david.sherw...@arm.com>

gcc/
        * tree.h (get_inner_reference): Add a version that returns the
        offset and size as poly_int64_pods rather than HOST_WIDE_INTs.
        * cfgexpand.c (expand_debug_expr): Track polynomial offsets.  Simply
        the case in which bitpos is not associated with the first byte.

Index: gcc/tree.h
===================================================================
--- gcc/tree.h  2017-10-23 17:11:40.253962440 +0100
+++ gcc/tree.h  2017-10-23 17:18:40.711668346 +0100
@@ -5610,6 +5610,17 @@ extern bool complete_ctor_at_level_p (co
    the access position and size.  */
 extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
                                 tree *, machine_mode *, int *, int *, int *);
+/* Temporary.  */
+inline tree
+get_inner_reference (tree exp, poly_int64_pod *pbitsize,
+                    poly_int64_pod *pbitpos, tree *poffset,
+                    machine_mode *pmode, int *punsignedp,
+                    int *preversep, int *pvolatilep)
+{
+  return get_inner_reference (exp, &pbitsize->coeffs[0], &pbitpos->coeffs[0],
+                             poffset, pmode, punsignedp, preversep,
+                             pvolatilep);
+}
 
 extern tree build_personality_function (const char *);
 
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c     2017-10-23 17:16:59.700268356 +0100
+++ gcc/cfgexpand.c     2017-10-23 17:18:40.711668346 +0100
@@ -4450,7 +4450,7 @@ expand_debug_expr (tree exp)
     case VIEW_CONVERT_EXPR:
       {
        machine_mode mode1;
-       HOST_WIDE_INT bitsize, bitpos;
+       poly_int64 bitsize, bitpos;
        tree offset;
        int reversep, volatilep = 0;
        tree tem
@@ -4458,7 +4458,7 @@ expand_debug_expr (tree exp)
                                 &unsignedp, &reversep, &volatilep);
        rtx orig_op0;
 
-       if (bitsize == 0)
+       if (known_zero (bitsize))
          return NULL;
 
        orig_op0 = op0 = expand_debug_expr (tem);
@@ -4501,19 +4501,14 @@ expand_debug_expr (tree exp)
            if (mode1 == VOIDmode)
              /* Bitfield.  */
              mode1 = smallest_int_mode_for_size (bitsize);
-           if (bitpos >= BITS_PER_UNIT)
+           poly_int64 bytepos = bits_to_bytes_round_down (bitpos);
+           if (maybe_nonzero (bytepos))
              {
-               op0 = adjust_address_nv (op0, mode1, bitpos / BITS_PER_UNIT);
-               bitpos %= BITS_PER_UNIT;
+               op0 = adjust_address_nv (op0, mode1, bytepos);
+               bitpos = num_trailing_bits (bitpos);
              }
-           else if (bitpos < 0)
-             {
-               HOST_WIDE_INT units
-                 = (-bitpos + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
-               op0 = adjust_address_nv (op0, mode1, -units);
-               bitpos += units * BITS_PER_UNIT;
-             }
-           else if (bitpos == 0 && bitsize == GET_MODE_BITSIZE (mode))
+           else if (known_zero (bitpos)
+                    && must_eq (bitsize, GET_MODE_BITSIZE (mode)))
              op0 = adjust_address_nv (op0, mode, 0);
            else if (GET_MODE (op0) != mode1)
              op0 = adjust_address_nv (op0, mode1, 0);
@@ -4524,17 +4519,18 @@ expand_debug_expr (tree exp)
            set_mem_attributes (op0, exp, 0);
          }
 
-       if (bitpos == 0 && mode == GET_MODE (op0))
+       if (known_zero (bitpos) && mode == GET_MODE (op0))
          return op0;
 
-        if (bitpos < 0)
+       if (may_lt (bitpos, 0))
           return NULL;
 
        if (GET_MODE (op0) == BLKmode)
          return NULL;
 
-       if ((bitpos % BITS_PER_UNIT) == 0
-           && bitsize == GET_MODE_BITSIZE (mode1))
+       poly_int64 bytepos;
+       if (multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
+           && must_eq (bitsize, GET_MODE_BITSIZE (mode1)))
          {
            machine_mode opmode = GET_MODE (op0);
 
@@ -4547,12 +4543,11 @@ expand_debug_expr (tree exp)
               debug stmts).  The gen_subreg below would rightfully
               crash, and the address doesn't really exist, so just
               drop it.  */
-           if (bitpos >= GET_MODE_BITSIZE (opmode))
+           if (must_ge (bitpos, GET_MODE_BITSIZE (opmode)))
              return NULL;
 
-           if ((bitpos % GET_MODE_BITSIZE (mode)) == 0)
-             return simplify_gen_subreg (mode, op0, opmode,
-                                         bitpos / BITS_PER_UNIT);
+           if (multiple_p (bitpos, GET_MODE_BITSIZE (mode)))
+             return simplify_gen_subreg (mode, op0, opmode, bytepos);
          }
 
        return simplify_gen_ternary (SCALAR_INT_MODE_P (GET_MODE (op0))
@@ -4562,7 +4557,8 @@ expand_debug_expr (tree exp)
                                     GET_MODE (op0) != VOIDmode
                                     ? GET_MODE (op0)
                                     : TYPE_MODE (TREE_TYPE (tem)),
-                                    op0, GEN_INT (bitsize), GEN_INT (bitpos));
+                                    op0, gen_int_mode (bitsize, word_mode),
+                                    gen_int_mode (bitpos, word_mode));
       }
 
     case ABS_EXPR:

Reply via email to