diff mbox series

Try harder to find base object by expanding base address

Message ID DB5PR0801MB2742327C5CFB31929C0F66D2E7480@DB5PR0801MB2742.eurprd08.prod.outlook.com
State New
Headers show
Series Try harder to find base object by expanding base address | expand

Commit Message

Bin Cheng Oct. 13, 2017, 3:04 p.m. UTC
Hi,
I ran into this when investigating PR82369 which we failed to find base object.
This simple patch tries harder to find base object by expanding base address
in alloc_iv.  In general, we don't want to do aggressive expansion, but this
case is fine because finding base object means reduction happened during the
expansion.  And it's good to have base object for address type iv_uses.
Bootstrap and test on x86_64 and AArch64.  Is it OK?

Thanks,
bin
2017-10-12  Bin Cheng  <bin.cheng@arm.com>

	* tree-scalar-evolution.c (alloc_iv): New parameter controlling
	base expansion for finding base object.
	(find_interesting_uses_address): Adjust call to alloc_iv.

gcc/testsuite
2017-10-12  Bin Cheng  <bin.cheng@arm.com>

	* gcc.dg/tree-ssa/ivopt_6.c: New test.

Comments

Richard Biener Oct. 19, 2017, 11:18 a.m. UTC | #1
On Fri, Oct 13, 2017 at 5:04 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
> Hi,
> I ran into this when investigating PR82369 which we failed to find base object.
> This simple patch tries harder to find base object by expanding base address
> in alloc_iv.  In general, we don't want to do aggressive expansion, but this
> case is fine because finding base object means reduction happened during the
> expansion.

I'm not sure.  Does simplification happen for the testcase when expanding?

>  And it's good to have base object for address type iv_uses.

Because we find related candidates via base-object?

It looks like we could avoid excessive expansion by doing
determine_base_object together with expr expansion given
the base object search is linear.  We can simply follow
SSA defs until we reach a suitable base and upon unwinding
build the base expression?

Richard.

> Bootstrap and test on x86_64 and AArch64.  Is it OK?
>
> Thanks,
> bin
> 2017-10-12  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-scalar-evolution.c (alloc_iv): New parameter controlling
>         base expansion for finding base object.
>         (find_interesting_uses_address): Adjust call to alloc_iv.
>
> gcc/testsuite
> 2017-10-12  Bin Cheng  <bin.cheng@arm.com>
>
>         * gcc.dg/tree-ssa/ivopt_6.c: New test.
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ivopt_6.c b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_6.c
new file mode 100644
index 0000000..de94b88
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_6.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+
+typedef unsigned long int uintptr_t;
+typedef long unsigned int size_t;
+typedef long int ptrdiff_t;
+
+void foo (unsigned char *restrict dst, unsigned char *restrict src, size_t bytes)
+{
+  uintptr_t end_dst = (uintptr_t) (dst + bytes);
+  uintptr_t srcu = (uintptr_t) src, dstu = (uintptr_t) dst;
+  ptrdiff_t src_dst_offset = srcu - 2 * dstu;
+
+  do {
+     unsigned char v0 = *(unsigned char *) (dstu * 2 + src_dst_offset);
+     unsigned char v1 = *(unsigned char *) ((dstu * 2 + src_dst_offset) + 1);
+     unsigned char res = v1 + v0;
+
+     *((unsigned char*) dstu) = res;
+     dstu += 16;
+  } while (dstu < end_dst);
+}
+/* { dg-final { scan-tree-dump-times "Type:\tADDRESS" 3 "ivopts" } } */
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index bbea619..4ccdf32 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1160,11 +1160,12 @@  contain_complex_addr_expr (tree expr)
 }
 
 /* Allocates an induction variable with given initial value BASE and step STEP
-   for loop LOOP.  NO_OVERFLOW implies the iv doesn't overflow.  */
+   for loop LOOP.  NO_OVERFLOW implies the iv doesn't overflow.  If EXPAND_P
+   is true, this function expands base address to find base object.  */
 
 static struct iv *
 alloc_iv (struct ivopts_data *data, tree base, tree step,
-	  bool no_overflow = false)
+	  bool no_overflow = false, bool expand_p = false)
 {
   tree expr = base;
   struct iv *iv = (struct iv*) obstack_alloc (&data->iv_obstack,
@@ -1185,8 +1186,22 @@  alloc_iv (struct ivopts_data *data, tree base, tree step,
       base = fold_convert (TREE_TYPE (base), aff_combination_to_tree (&comb));
     }
 
+  tree base_object = determine_base_object (base);
+  /* Try harder to find base object by expanding base.  */
+  if (expand_p && base_object == NULL_TREE)
+    {
+      aff_tree comb;
+      expr = unshare_expr (base);
+      tree_to_aff_combination_expand (base, TREE_TYPE (base), &comb,
+				      &data->name_expansion_cache);
+      base = fold_convert (TREE_TYPE (base), aff_combination_to_tree (&comb));
+      base_object = determine_base_object (base);
+      /* Fall back to unexpanded base if no base object is found.  */
+      if (!base_object)
+	base = expr;
+    }
   iv->base = base;
-  iv->base_object = determine_base_object (base);
+  iv->base_object = base_object;
   iv->step = step;
   iv->biv_p = false;
   iv->nonlin_use = NULL;
@@ -2365,7 +2380,7 @@  find_interesting_uses_address (struct ivopts_data *data, gimple *stmt,
 	}
     }
 
-  civ = alloc_iv (data, base, step);
+  civ = alloc_iv (data, base, step, false, true);
   /* Fail if base object of this memory reference is unknown.  */
   if (civ->base_object == NULL_TREE)
     goto fail;