Make dse.c use offset/width instead of start/end
authorRichard Sandiford <richard.sandiford@linaro.org>
Fri, 15 Dec 2017 13:12:25 +0000 (13:12 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 15 Dec 2017 13:12:25 +0000 (13:12 +0000)
store_info and read_info_type in dse.c represented the ranges as
start/end, but a lot of the internal code used offset/width instead.
Using offset/width throughout fits better with the poly_int.h
range-checking functions.

2017-12-15  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* dse.c (store_info, read_info_type): Replace begin and end with
offset and width.
(print_range): New function.
(set_all_positions_unneeded, any_positions_needed_p)
(check_mem_read_rtx, scan_stores, scan_reads, dse_step5): Update
accordingly.
(record_store): Likewise.  Optimize the case in which all positions
are unneeded.
(get_stored_val): Replace read_begin and read_end with read_offset
and read_width.
(replace_read): Update call accordingly.

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

gcc/ChangeLog
gcc/dse.c

index 5908dd55679a7d364c258be685641f1343fe02f1..e83d5beaa1a03671056e909440a8e2728ff0bbce 100644 (file)
@@ -1,3 +1,19 @@
+2017-12-15  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * dse.c (store_info, read_info_type): Replace begin and end with
+       offset and width.
+       (print_range): New function.
+       (set_all_positions_unneeded, any_positions_needed_p)
+       (check_mem_read_rtx, scan_stores, scan_reads, dse_step5): Update
+       accordingly.
+       (record_store): Likewise.  Optimize the case in which all positions
+       are unneeded.
+       (get_stored_val): Replace read_begin and read_end with read_offset
+       and read_width.
+       (replace_read): Update call accordingly.
+
 2017-12-15  Bin Cheng  <bin.cheng@arm.com>
 
        * gimple-loop-interchange.cc (STMT_COST_RATIO): New macro.
index 1b34f4f028531e02b111613c4086dbaea9aaedb9..fbc6b25ac1ecc1678894c2267980c3cdeaf39266 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -243,9 +243,12 @@ struct store_info
   /* Canonized MEM address for use by canon_true_dependence.  */
   rtx mem_addr;
 
-  /* The offset of the first and byte before the last byte associated
-     with the operation.  */
-  HOST_WIDE_INT begin, end;
+  /* The offset of the first byte associated with the operation.  */
+  HOST_WIDE_INT offset;
+
+  /* The number of bytes covered by the operation.  This is always exact
+     and known (rather than -1).  */
+  HOST_WIDE_INT width;
 
   union
     {
@@ -261,7 +264,7 @@ struct store_info
          bitmap bmap;
 
          /* Number of set bits (i.e. unneeded bytes) in BITMAP.  If it is
-            equal to END - BEGIN, the whole store is unused.  */
+            equal to WIDTH, the whole store is unused.  */
          int count;
        } large;
     } positions_needed;
@@ -304,10 +307,11 @@ struct read_info_type
   /* The id of the mem group of the base address.  */
   int group_id;
 
-  /* The offset of the first and byte after the last byte associated
-     with the operation.  If begin == end == 0, the read did not have
-     a constant offset.  */
-  int begin, end;
+  /* The offset of the first byte associated with the operation.  */
+  HOST_WIDE_INT offset;
+
+  /* The number of bytes covered by the operation, or -1 if not known.  */
+  HOST_WIDE_INT width;
 
   /* The mem being read.  */
   rtx mem;
@@ -586,6 +590,18 @@ static bitmap kill_on_calls;
 
 /* The number of bits used in the global bitmaps.  */
 static unsigned int current_position;
+
+/* Print offset range [OFFSET, OFFSET + WIDTH) to FILE.  */
+
+static void
+print_range (FILE *file, poly_int64 offset, poly_int64 width)
+{
+  fprintf (file, "[");
+  print_dec (offset, file, SIGNED);
+  fprintf (file, "..");
+  print_dec (offset + width, file, SIGNED);
+  fprintf (file, ")");
+}
 \f
 /*----------------------------------------------------------------------------
    Zeroth step.
@@ -1212,10 +1228,9 @@ set_all_positions_unneeded (store_info *s_info)
 {
   if (__builtin_expect (s_info->is_large, false))
     {
-      int pos, end = s_info->end - s_info->begin;
-      for (pos = 0; pos < end; pos++)
-       bitmap_set_bit (s_info->positions_needed.large.bmap, pos);
-      s_info->positions_needed.large.count = end;
+      bitmap_set_range (s_info->positions_needed.large.bmap,
+                       0, s_info->width);
+      s_info->positions_needed.large.count = s_info->width;
     }
   else
     s_info->positions_needed.small_bitmask = HOST_WIDE_INT_0U;
@@ -1227,8 +1242,7 @@ static inline bool
 any_positions_needed_p (store_info *s_info)
 {
   if (__builtin_expect (s_info->is_large, false))
-    return (s_info->positions_needed.large.count
-           < s_info->end - s_info->begin);
+    return s_info->positions_needed.large.count < s_info->width;
   else
     return (s_info->positions_needed.small_bitmask != HOST_WIDE_INT_0U);
 }
@@ -1361,8 +1375,12 @@ record_store (rtx body, bb_info_t bb_info)
       set_usage_bits (group, offset, width, expr);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
-       fprintf (dump_file, " processing const base store gid=%d[%d..%d)\n",
-                group_id, (int)offset, (int)(offset+width));
+       {
+         fprintf (dump_file, " processing const base store gid=%d",
+                  group_id);
+         print_range (dump_file, offset, width);
+         fprintf (dump_file, "\n");
+       }
     }
   else
     {
@@ -1374,8 +1392,11 @@ record_store (rtx body, bb_info_t bb_info)
       group_id = -1;
 
       if (dump_file && (dump_flags & TDF_DETAILS))
-       fprintf (dump_file, " processing cselib store [%d..%d)\n",
-                (int)offset, (int)(offset+width));
+       {
+         fprintf (dump_file, " processing cselib store ");
+         print_range (dump_file, offset, width);
+         fprintf (dump_file, "\n");
+       }
     }
 
   const_rhs = rhs = NULL_RTX;
@@ -1441,18 +1462,21 @@ record_store (rtx body, bb_info_t bb_info)
        {
          HOST_WIDE_INT i;
          if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file, "    trying store in insn=%d gid=%d[%d..%d)\n",
-                    INSN_UID (ptr->insn), s_info->group_id,
-                    (int)s_info->begin, (int)s_info->end);
+           {
+             fprintf (dump_file, "    trying store in insn=%d gid=%d",
+                      INSN_UID (ptr->insn), s_info->group_id);
+             print_range (dump_file, s_info->offset, s_info->width);
+             fprintf (dump_file, "\n");
+           }
 
          /* Even if PTR won't be eliminated as unneeded, if both
             PTR and this insn store the same constant value, we might
             eliminate this insn instead.  */
          if (s_info->const_rhs
              && const_rhs
-             && offset >= s_info->begin
-             && offset + width <= s_info->end
-             && all_positions_needed_p (s_info, offset - s_info->begin,
+             && known_subrange_p (offset, width,
+                                  s_info->offset, s_info->width)
+             && all_positions_needed_p (s_info, offset - s_info->offset,
                                         width))
            {
              if (GET_MODE (mem) == BLKmode)
@@ -1468,8 +1492,7 @@ record_store (rtx body, bb_info_t bb_info)
                {
                  rtx val;
                  start_sequence ();
-                 val = get_stored_val (s_info, GET_MODE (mem),
-                                       offset, offset + width,
+                 val = get_stored_val (s_info, GET_MODE (mem), offset, width,
                                        BLOCK_FOR_INSN (insn_info->insn),
                                        true);
                  if (get_insns () != NULL)
@@ -1480,10 +1503,18 @@ record_store (rtx body, bb_info_t bb_info)
                }
            }
 
-         for (i = MAX (offset, s_info->begin);
-              i < offset + width && i < s_info->end;
-              i++)
-           set_position_unneeded (s_info, i - s_info->begin);
+         if (known_subrange_p (s_info->offset, s_info->width, offset, width))
+           /* The new store touches every byte that S_INFO does.  */
+           set_all_positions_unneeded (s_info);
+         else
+           {
+             HOST_WIDE_INT begin_unneeded = offset - s_info->offset;
+             HOST_WIDE_INT end_unneeded = begin_unneeded + width;
+             begin_unneeded = MAX (begin_unneeded, 0);
+             end_unneeded = MIN (end_unneeded, s_info->width);
+             for (i = begin_unneeded; i < end_unneeded; ++i)
+               set_position_unneeded (s_info, i);
+           }
        }
       else if (s_info->rhs)
        /* Need to see if it is possible for this store to overwrite
@@ -1541,8 +1572,8 @@ record_store (rtx body, bb_info_t bb_info)
       store_info->positions_needed.small_bitmask = lowpart_bitmask (width);
     }
   store_info->group_id = group_id;
-  store_info->begin = offset;
-  store_info->end = offset + width;
+  store_info->offset = offset;
+  store_info->width = width;
   store_info->is_set = GET_CODE (body) == SET;
   store_info->rhs = rhs;
   store_info->const_rhs = const_rhs;
@@ -1704,39 +1735,38 @@ look_for_hardregs (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
 }
 
 /* Helper function for replace_read and record_store.
-   Attempt to return a value stored in STORE_INFO, from READ_BEGIN
-   to one before READ_END bytes read in READ_MODE.  Return NULL
+   Attempt to return a value of mode READ_MODE stored in STORE_INFO,
+   consisting of READ_WIDTH bytes starting from READ_OFFSET.  Return NULL
    if not successful.  If REQUIRE_CST is true, return always constant.  */
 
 static rtx
 get_stored_val (store_info *store_info, machine_mode read_mode,
-               HOST_WIDE_INT read_begin, HOST_WIDE_INT read_end,
+               HOST_WIDE_INT read_offset, HOST_WIDE_INT read_width,
                basic_block bb, bool require_cst)
 {
   machine_mode store_mode = GET_MODE (store_info->mem);
-  int shift;
-  int access_size; /* In bytes.  */
+  HOST_WIDE_INT gap;
   rtx read_reg;
 
   /* To get here the read is within the boundaries of the write so
      shift will never be negative.  Start out with the shift being in
      bytes.  */
   if (store_mode == BLKmode)
-    shift = 0;
+    gap = 0;
   else if (BYTES_BIG_ENDIAN)
-    shift = store_info->end - read_end;
+    gap = ((store_info->offset + store_info->width)
+          - (read_offset + read_width));
   else
-    shift = read_begin - store_info->begin;
-
-  access_size = shift + GET_MODE_SIZE (read_mode);
-
-  /* From now on it is bits.  */
-  shift *= BITS_PER_UNIT;
+    gap = read_offset - store_info->offset;
 
-  if (shift)
-    read_reg = find_shift_sequence (access_size, store_info, read_mode, shift,
-                                   optimize_bb_for_speed_p (bb),
-                                   require_cst);
+  if (gap != 0)
+    {
+      HOST_WIDE_INT shift = gap * BITS_PER_UNIT;
+      HOST_WIDE_INT access_size = GET_MODE_SIZE (read_mode) + gap;
+      read_reg = find_shift_sequence (access_size, store_info, read_mode,
+                                     shift, optimize_bb_for_speed_p (bb),
+                                     require_cst);
+    }
   else if (store_mode == BLKmode)
     {
       /* The store is a memset (addr, const_val, const_size).  */
@@ -1839,7 +1869,7 @@ replace_read (store_info *store_info, insn_info_t store_insn,
   start_sequence ();
   bb = BLOCK_FOR_INSN (read_insn->insn);
   read_reg = get_stored_val (store_info,
-                            read_mode, read_info->begin, read_info->end,
+                            read_mode, read_info->offset, read_info->width,
                             bb, false);
   if (read_reg == NULL_RTX)
     {
@@ -2000,8 +2030,8 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info)
   read_info = read_info_type_pool.allocate ();
   read_info->group_id = group_id;
   read_info->mem = mem;
-  read_info->begin = offset;
-  read_info->end = offset + width;
+  read_info->offset = offset;
+  read_info->width = width;
   read_info->next = insn_info->read_rec;
   insn_info->read_rec = read_info;
   if (group_id < 0)
@@ -2027,8 +2057,11 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info)
            fprintf (dump_file, " processing const load gid=%d[BLK]\n",
                     group_id);
          else
-           fprintf (dump_file, " processing const load gid=%d[%d..%d)\n",
-                    group_id, (int)offset, (int)(offset+width));
+           {
+             fprintf (dump_file, " processing const load gid=%d", group_id);
+             print_range (dump_file, offset, width);
+             fprintf (dump_file, "\n");
+           }
        }
 
       while (i_ptr)
@@ -2066,19 +2099,20 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info)
              else
                {
                  if (store_info->rhs
-                     && offset >= store_info->begin
-                     && offset + width <= store_info->end
+                     && known_subrange_p (offset, width, store_info->offset,
+                                          store_info->width)
                      && all_positions_needed_p (store_info,
-                                                offset - store_info->begin,
+                                                offset - store_info->offset,
                                                 width)
                      && replace_read (store_info, i_ptr, read_info,
                                       insn_info, loc, bb_info->regs_live))
                    return;
 
                  /* The bases are the same, just see if the offsets
-                    overlap.  */
-                 if ((offset < store_info->end)
-                     && (offset + width > store_info->begin))
+                    could overlap.  */
+                 if (ranges_maybe_overlap_p (offset, width,
+                                             store_info->offset,
+                                             store_info->width))
                    remove = true;
                }
            }
@@ -2133,11 +2167,10 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info)
          if (store_info->rhs
              && store_info->group_id == -1
              && store_info->cse_base == base
-             && width != -1
-             && offset >= store_info->begin
-             && offset + width <= store_info->end
+             && known_subrange_p (offset, width, store_info->offset,
+                                  store_info->width)
              && all_positions_needed_p (store_info,
-                                        offset - store_info->begin, width)
+                                        offset - store_info->offset, width)
              && replace_read (store_info, i_ptr,  read_info, insn_info, loc,
                               bb_info->regs_live))
            return;
@@ -2789,16 +2822,19 @@ scan_stores (store_info *store_info, bitmap gen, bitmap kill)
       group_info *group_info
        = rtx_group_vec[store_info->group_id];
       if (group_info->process_globally)
-       for (i = store_info->begin; i < store_info->end; i++)
-         {
-           int index = get_bitmap_index (group_info, i);
-           if (index != 0)
-             {
-               bitmap_set_bit (gen, index);
-               if (kill)
-                 bitmap_clear_bit (kill, index);
-             }
-         }
+       {
+         HOST_WIDE_INT end = store_info->offset + store_info->width;
+         for (i = store_info->offset; i < end; i++)
+           {
+             int index = get_bitmap_index (group_info, i);
+             if (index != 0)
+               {
+                 bitmap_set_bit (gen, index);
+                 if (kill)
+                   bitmap_clear_bit (kill, index);
+               }
+           }
+       }
       store_info = store_info->next;
     }
 }
@@ -2848,9 +2884,9 @@ scan_reads (insn_info_t insn_info, bitmap gen, bitmap kill)
            {
              if (i == read_info->group_id)
                {
-                 if (read_info->begin > read_info->end)
+                 if (!known_size_p (read_info->width))
                    {
-                     /* Begin > end for block mode reads.  */
+                     /* Handle block mode reads.  */
                      if (kill)
                        bitmap_ior_into (kill, group->group_kill);
                      bitmap_and_compl_into (gen, group->group_kill);
@@ -2860,7 +2896,8 @@ scan_reads (insn_info_t insn_info, bitmap gen, bitmap kill)
                      /* The groups are the same, just process the
                         offsets.  */
                      HOST_WIDE_INT j;
-                     for (j = read_info->begin; j < read_info->end; j++)
+                     HOST_WIDE_INT end = read_info->offset + read_info->width;
+                     for (j = read_info->offset; j < end; j++)
                        {
                          int index = get_bitmap_index (group, j);
                          if (index != 0)
@@ -3279,7 +3316,8 @@ dse_step5 (void)
              HOST_WIDE_INT i;
              group_info *group_info = rtx_group_vec[store_info->group_id];
 
-             for (i = store_info->begin; i < store_info->end; i++)
+             HOST_WIDE_INT end = store_info->offset + store_info->width;
+             for (i = store_info->offset; i < end; i++)
                {
                  int index = get_bitmap_index (group_info, i);