poly_int: expand_debug_expr
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 20 Dec 2017 12:56:24 +0000 (12:56 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 20 Dec 2017 12:56:24 +0000 (12:56 +0000)
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-12-20  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@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.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255892

gcc/ChangeLog
gcc/cfgexpand.c
gcc/tree.h

index 70e8c1a5e46270053b93f1f31a14f779411bb893..3aca9c59ccd5de472136f775b833d7ac9ff2e337 100644 (file)
@@ -1,3 +1,12 @@
+2017-12-20  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * 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.
+
 2017-12-20  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 324e0972b50309fe04034390b7563d770a835992..d509326b9e649adfa3c238c13fe47072e7eb6724 100644 (file)
@@ -4470,7 +4470,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
@@ -4478,7 +4478,7 @@ expand_debug_expr (tree exp)
                                 &unsignedp, &reversep, &volatilep);
        rtx orig_op0;
 
-       if (bitsize == 0)
+       if (known_eq (bitsize, 0))
          return NULL;
 
        orig_op0 = op0 = expand_debug_expr (tem);
@@ -4521,19 +4521,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_ne (bytepos, 0))
              {
-               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_eq (bitpos, 0)
+                    && known_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);
@@ -4544,17 +4539,18 @@ expand_debug_expr (tree exp)
            set_mem_attributes (op0, exp, 0);
          }
 
-       if (bitpos == 0 && mode == GET_MODE (op0))
+       if (known_eq (bitpos, 0) && mode == GET_MODE (op0))
          return op0;
 
-        if (bitpos < 0)
+       if (maybe_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)
+           && known_eq (bitsize, GET_MODE_BITSIZE (mode1)))
          {
            machine_mode opmode = GET_MODE (op0);
 
@@ -4567,12 +4563,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 (known_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))
@@ -4582,7 +4577,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:
index a7b8c2f400c9d7badc27b090e211b8dfd7fbae1b..db87321882797a4426057eeb96f86b17634e240c 100644 (file)
@@ -5638,6 +5638,17 @@ extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
    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 *);