]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-ssa-loop-ivopts.c (alloc_iv): Lower address expressions.
authorBin Cheng <bin.cheng@arm.com>
Thu, 7 Nov 2013 08:12:34 +0000 (08:12 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Thu, 7 Nov 2013 08:12:34 +0000 (08:12 +0000)
* tree-ssa-loop-ivopts.c (alloc_iv): Lower address expressions.
* tree-affine.c (get_inner_reference_aff): Return base.
* tree-affine.h (get_inner_reference_aff): Change prototype.

* gcc.dg/tree-ssa/loop-2.c: Refine check condition.
* gcc.dg/tree-ssa/ivopt_infer_2.c: Ditto.
* gcc.dg/tree-ssa/ivopt_mult_3.c: Ditto.

From-SVN: r204497

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ivopt_infer_2.c
gcc/testsuite/gcc.dg/tree-ssa/ivopt_mult_3.c
gcc/testsuite/gcc.dg/tree-ssa/loop-2.c
gcc/tree-affine.c
gcc/tree-affine.h
gcc/tree-ssa-loop-ivopts.c

index 75603e79382f8d1f15c5f3ab147b37e89fa5abc4..fcbcbb5466f9a1a89bb6be98d554097e985e2053 100644 (file)
@@ -1,3 +1,9 @@
+2013-11-07  Bin Cheng  <bin.cheng@arm.com>
+
+       * tree-ssa-loop-ivopts.c (alloc_iv): Lower address expressions.
+       * tree-affine.c (get_inner_reference_aff): Return base.
+       * tree-affine.h (get_inner_reference_aff): Change prototype.
+
 2013-11-06  Tobias Burnus  <burnus@net-b.de>
 
        * doc/invoke.texi (Wdate-time): Fix typo.
index b857d00f851a1dc8dbf917bed71505d1690308fe..c89765b998c157f9668c8eb2b4ee27aeba804eb7 100644 (file)
@@ -1,3 +1,9 @@
+2013-11-07  Bin Cheng  <bin.cheng@arm.com>
+
+       * gcc.dg/tree-ssa/loop-2.c: Refine check condition.
+       * gcc.dg/tree-ssa/ivopt_infer_2.c: Ditto.
+       * gcc.dg/tree-ssa/ivopt_mult_3.c: Ditto.
+
 2013-11-06  DJ Delorie  <dj@redhat.com>
 
        * gcc.dg/mismatch-decl-1.c: New test.
index 4c5a54b9af4522f669161f47a5fb1c7383d777d6..c0f6398d827cd261427b3e9dd7cec82830550e1a 100644 (file)
@@ -7,7 +7,8 @@
 
 extern char a[];
 
-/* Can not infer loop iteration from array -- exit test can not be replaced.  */
+/* Can not infer loop iteration from array -- exit test can not be
+   replaced by the array address.  */
 void foo (unsigned int i_width, TYPE dst)
 {
   unsigned long long i = 0;
@@ -21,5 +22,5 @@ void foo (unsigned int i_width, TYPE dst)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "Replacing" 0 "ivopts"} } */
+/* { dg-final { scan-tree-dump-times "\[^:\]*if \\(.*j_\[0-9\]+.*\\)" 1 "ivopts"} } */
 /* { dg-final { cleanup-tree-dump "ivopts" } } */
index dc78a43f73f51021eacd9b2569063ddab8136dee..25ae845f71e21f2bcaa7a26ec8baf4ebaf4abfc1 100644 (file)
@@ -18,5 +18,5 @@ long foo(long* p, long* p2, int N1, int N2)
   return s;
 }
 
-/* { dg-final { scan-tree-dump-times "Replacing" 1 "ivopts"} } */
+/* { dg-final { scan-tree-dump-times "Replacing exit test: if \\(.*p2.*\\)" 1 "ivopts"} } */
 /* { dg-final { cleanup-tree-dump "ivopts" } } */
index 3426827783c7238439022b11b875672c1897a2d8..f43a6d8eb77ea0fdceda05e4781bf7940b5130cc 100644 (file)
@@ -27,7 +27,7 @@ void xxx(void)
 
 /* { dg-final { scan-tree-dump-times " \\* \[^\\n\\r\]*=" 0 "optimized" } } */
 /* { dg-final { scan-tree-dump-times "\[^\\n\\r\]*= \\* " 0 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "MEM" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MEM\\\[base" 1 "optimized" } } */
 
 /* 17 * iter should be strength reduced.  */
 
index 81da521277f5d6fb224ad20c2240021035558475..b492ff0a2118456cb1a41b1ed44f384ab7a5396b 100644 (file)
@@ -874,10 +874,11 @@ debug_aff (aff_tree *val)
   fprintf (stderr, "\n");
 }
 
-/* Returns address of the reference REF in ADDR.  The size of the accessed
-   location is stored to SIZE.  */
+/* Computes address of the reference REF in ADDR.  The size of the accessed
+   location is stored to SIZE.  Returns the ultimate containing object to
+   which REF refers.  */
 
-void
+tree
 get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size)
 {
   HOST_WIDE_INT bitsize, bitpos;
@@ -904,6 +905,8 @@ get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size)
   aff_combination_add (addr, &tmp);
 
   *size = double_int::from_shwi ((bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
+
+  return base;
 }
 
 /* Returns true if a region of size SIZE1 at position 0 and a region of
index b2558f7a4bdcd5481dda656e3b9070c16db81805..86f90d82da08a227f5d0aecf56969d68bea39f84 100644 (file)
@@ -74,7 +74,7 @@ bool aff_combination_constant_multiple_p (aff_tree *, aff_tree *, double_int *);
 void aff_combination_expand (aff_tree *, struct pointer_map_t **);
 void tree_to_aff_combination_expand (tree, tree, aff_tree *,
                                     struct pointer_map_t **);
-void get_inner_reference_aff (tree, aff_tree *, double_int *);
+tree get_inner_reference_aff (tree, aff_tree *, double_int *);
 void free_affine_expand_cache (struct pointer_map_t **);
 bool aff_comb_cannot_overlap_p (aff_tree *, double_int, double_int);
 
index 0210dbbad3df77299bc5ad12522c798038243ad6..220aae6878b762f0506d455e68de9c056488e7c8 100644 (file)
@@ -924,11 +924,30 @@ determine_base_object (tree expr)
 static struct iv *
 alloc_iv (tree base, tree step)
 {
+  tree base_object = base;
   struct iv *iv = XCNEW (struct iv);
   gcc_assert (step != NULL_TREE);
 
+  /* Lower all address expressions except ones with DECL_P as operand.
+     By doing this:
+       1) More accurate cost can be computed for address expressions;
+       2) Duplicate candidates won't be created for bases in different
+          forms, like &a[0] and &a.  */
+  STRIP_NOPS (base_object);
+  if (TREE_CODE (base_object) == ADDR_EXPR
+      && !DECL_P (TREE_OPERAND (base_object, 0)))
+    {
+      aff_tree comb;
+      double_int size;
+      base_object = get_inner_reference_aff (TREE_OPERAND (base_object, 0),
+                                            &comb, &size);
+      gcc_assert (base_object != NULL_TREE);
+      base_object = build_fold_addr_expr (base_object);
+      base = fold_convert (TREE_TYPE (base), aff_combination_to_tree (&comb));
+    }
+
   iv->base = base;
-  iv->base_object = determine_base_object (base);
+  iv->base_object = determine_base_object (base_object);
   iv->step = step;
   iv->biv_p = false;
   iv->have_use_for = false;