public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH GCC8][07/33]Offset validity check in address expression
@ 2017-04-18 10:41 Bin Cheng
  2017-04-24 10:37 ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Bin Cheng @ 2017-04-18 10:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: nd

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]

Hi,
For now, we check validity of offset by computing the maximum offset then checking if
offset is smaller than the max offset.  This is inaccurate, for example, some targets
may require offset to be aligned by power of 2.  This patch introduces new interface
checking validity of offset.  It also buffers rtx among different calls.

Is it OK?

Thanks,
bin
2017-04-11  Bin Cheng  <bin.cheng@arm.com>

	* tree-ssa-loop-ivopts.c (compute_max_addr_offset): Delete.
	(addr_offset_valid_p): New function.
	(split_address_groups): Check offset validity with above function.

[-- Attachment #2: 0007-offset-check-in-group-split-20170220.txt --]
[-- Type: text/plain, Size: 5465 bytes --]

From fe33bd3fe9a1dbf1a10ae50bfeecc5a9d0b6c759 Mon Sep 17 00:00:00 2001
From: Bin Cheng <binche01@e108451-lin.cambridge.arm.com>
Date: Tue, 28 Feb 2017 16:19:27 +0000
Subject: [PATCH 07/33] offset-check-in-group-split-20170220.txt

---
 gcc/tree-ssa-loop-ivopts.c | 103 +++++++++++++++++----------------------------
 1 file changed, 38 insertions(+), 65 deletions(-)

diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 840bde4..5ab1d29 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -2460,67 +2460,42 @@ find_interesting_uses_outside (struct ivopts_data *data, edge exit)
     }
 }
 
-/* Compute maximum offset of [base + offset] addressing mode
-   for memory reference represented by USE.  */
+/* Return TRUE if OFFSET is within the range of [base + offset] addressing
+   mode for memory reference represented by USE.  */
 
-static HOST_WIDE_INT
-compute_max_addr_offset (struct iv_use *use)
+static bool
+addr_offset_valid_p (struct iv_use *use, HOST_WIDE_INT offset)
 {
-  int width;
   rtx reg, addr;
-  HOST_WIDE_INT i, off;
   unsigned list_index, num;
   addr_space_t as;
   machine_mode mem_mode, addr_mode;
-  static vec<HOST_WIDE_INT> max_offset_list;
-
+  auto_vec<rtx> addr_list;
   as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base));
   mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));
 
-  num = max_offset_list.length ();
+  num = addr_list.length ();
   list_index = (unsigned) as * MAX_MACHINE_MODE + (unsigned) mem_mode;
   if (list_index >= num)
     {
-      max_offset_list.safe_grow (list_index + MAX_MACHINE_MODE);
-      for (; num < max_offset_list.length (); num++)
-	max_offset_list[num] = -1;
+      addr_list.safe_grow_cleared (list_index + MAX_MACHINE_MODE);
+      for (; num < addr_list.length (); num++)
+	addr_list[num] = NULL;
     }
 
-  off = max_offset_list[list_index];
-  if (off != -1)
-    return off;
-
-  addr_mode = targetm.addr_space.address_mode (as);
-  reg = gen_raw_REG (addr_mode, LAST_VIRTUAL_REGISTER + 1);
-  addr = gen_rtx_fmt_ee (PLUS, addr_mode, reg, NULL_RTX);
-
-  width = GET_MODE_BITSIZE (addr_mode) - 1;
-  if (width > (HOST_BITS_PER_WIDE_INT - 1))
-    width = HOST_BITS_PER_WIDE_INT - 1;
-
-  for (i = width; i > 0; i--)
+  addr = addr_list[list_index];
+  if (!addr)
     {
-      off = (HOST_WIDE_INT_1U << i) - 1;
-      XEXP (addr, 1) = gen_int_mode (off, addr_mode);
-      if (memory_address_addr_space_p (mem_mode, addr, as))
-	break;
-
-      /* For some strict-alignment targets, the offset must be naturally
-	 aligned.  Try an aligned offset if mem_mode is not QImode.  */
-      off = (HOST_WIDE_INT_1U << i);
-      if (off > GET_MODE_SIZE (mem_mode) && mem_mode != QImode)
-	{
-	  off -= GET_MODE_SIZE (mem_mode);
-	  XEXP (addr, 1) = gen_int_mode (off, addr_mode);
-	  if (memory_address_addr_space_p (mem_mode, addr, as))
-	    break;
-	}
+      addr_mode = targetm.addr_space.address_mode (as);
+      reg = gen_raw_REG (addr_mode, LAST_VIRTUAL_REGISTER + 1);
+      addr = gen_rtx_fmt_ee (PLUS, addr_mode, reg, NULL_RTX);
+      addr_list[list_index] = addr;
     }
-  if (i == 0)
-    off = 0;
+  else
+    addr_mode = GET_MODE (addr);
 
-  max_offset_list[list_index] = off;
-  return off;
+  XEXP (addr, 1) = gen_int_mode (offset, addr_mode);
+  return (memory_address_addr_space_p (mem_mode, addr, as));
 }
 
 /* Comparison function to sort group in ascending order of addr_offset.  */
@@ -2599,14 +2574,12 @@ static void
 split_address_groups (struct ivopts_data *data)
 {
   unsigned int i, j;
-  HOST_WIDE_INT max_offset = -1;
-
-  /* Reset max offset to split all small groups.  */
-  if (split_small_address_groups_p (data))
-    max_offset = 0;
+  /* Always split group.  */
+  bool split_p = split_small_address_groups_p (data);
 
   for (i = 0; i < data->vgroups.length (); i++)
     {
+      struct iv_group *new_group = NULL;
       struct iv_group *group = data->vgroups[i];
       struct iv_use *use = group->vuses[0];
 
@@ -2615,29 +2588,29 @@ split_address_groups (struct ivopts_data *data)
       if (group->vuses.length () == 1)
 	continue;
 
-      if (max_offset != 0)
-	max_offset = compute_max_addr_offset (use);
+      gcc_assert (group->type == USE_ADDRESS);
 
-      for (j = 1; j < group->vuses.length (); j++)
+      for (j = 1; j < group->vuses.length ();)
 	{
 	  struct iv_use *next = group->vuses[j];
+	  HOST_WIDE_INT offset = next->addr_offset - use->addr_offset;
 
-	  /* Only uses with offset that can fit in offset part against
-	     the first use can be grouped together.  */
-	  if (next->addr_offset - use->addr_offset
-	      > (unsigned HOST_WIDE_INT) max_offset)
-	    break;
+	  /* Split group if aksed to, or the offset against the first
+	     use can't fit in offset part of addressing mode.  IV uses
+	     having the same offset are still kept in one group.  */
+	  if (offset != 0 &&
+	      (split_p || !addr_offset_valid_p (use, offset)))
+	    {
+	      if (!new_group)
+		new_group = record_group (data, group->type);
+	      group->vuses.ordered_remove (j);
+	      new_group->vuses.safe_push (next);
+	      continue;
+	    }
 
 	  next->id = j;
 	  next->group_id = group->id;
-	}
-      /* Split group.  */
-      if (j < group->vuses.length ())
-	{
-	  struct iv_group *new_group = record_group (data, group->type);
-	  new_group->vuses.safe_splice (group->vuses);
-	  new_group->vuses.block_remove (0, j);
-	  group->vuses.truncate (j);
+	  j++;
 	}
     }
 }
-- 
1.9.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-05-05  7:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-18 10:41 [PATCH GCC8][07/33]Offset validity check in address expression Bin Cheng
2017-04-24 10:37 ` Richard Biener
2017-05-02 17:08   ` Bin.Cheng
2017-05-03  9:54     ` Richard Biener
2017-05-04 15:19       ` Bin.Cheng
2017-05-05  7:23         ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).