re PR middle-end/71734 (FAIL: libgomp.fortran/simd4.f90 -O3 -g execution test)
authorYuri Rumyantsev <ysrumyan@gmail.com>
Wed, 10 Aug 2016 15:03:02 +0000 (15:03 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 10 Aug 2016 15:03:02 +0000 (08:03 -0700)
Fix PR tree-optimization/71734

2016-08-10  Yuri Rumyantsev  <ysrumyan@gmail.com>

PR tree-optimization/71734
* tree-ssa-loop-im.c (ref_indep_loop_p): Add new argument
REF_LOOP, invoke ref_indep_loop_p_1.
(outermost_indep_loop): Pass LOOP argumnet where REF was defined
to ref_indep_loop_p.
(ref_indep_loop_p_1): Fix commentary, add argument REF_LOOP,
combine it with ref_indep_lopp_p_2, update SAFELEN if only REF
is inside LOOP, do not cache dpendence value for loops with
non-zero SAFELEN.
(ref_indep_loop_p_2): Delete function.
(can_sm_ref_p): Pass LOOP as additional argument to
ref_indep_loop_p.

From-SVN: r239326

gcc/ChangeLog
gcc/tree-ssa-loop-im.c

index afa402028d7066caa6bf37b2e188a80184a03f11..a0a3698601fb6a8776e9f945dcb9d980cd7da430 100644 (file)
@@ -1,3 +1,18 @@
+2016-08-10  Yuri Rumyantsev  <ysrumyan@gmail.com>
+
+       PR tree-optimization/71734
+       * tree-ssa-loop-im.c (ref_indep_loop_p): Add new argument
+       REF_LOOP, invoke ref_indep_loop_p_1.
+       (outermost_indep_loop): Pass LOOP argumnet where REF was defined
+       to ref_indep_loop_p.
+       (ref_indep_loop_p_1): Fix commentary, add argument REF_LOOP,
+       combine it with ref_indep_lopp_p_2, update SAFELEN if only REF
+       is inside LOOP, do not cache dpendence value for loops with
+       non-zero SAFELEN.
+       (ref_indep_loop_p_2): Delete function.
+       (can_sm_ref_p): Pass LOOP as additional argument to
+       ref_indep_loop_p.
+
 2016-08-10  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/72853
index 947724bceff3ea8b01fd4b3049ccf339fdde6923..463db048cb6468da476ba0e499bb31c0a6384c30 100644 (file)
@@ -196,7 +196,7 @@ static struct
 static bitmap_obstack lim_bitmap_obstack;
 static obstack mem_ref_obstack;
 
-static bool ref_indep_loop_p (struct loop *, im_mem_ref *);
+static bool ref_indep_loop_p (struct loop *, im_mem_ref *, struct loop *);
 
 /* Minimum cost of an expensive expression.  */
 #define LIM_EXPENSIVE ((unsigned) PARAM_VALUE (PARAM_LIM_EXPENSIVE))
@@ -544,10 +544,10 @@ outermost_indep_loop (struct loop *outer, struct loop *loop, im_mem_ref *ref)
        aloop != loop;
        aloop = superloop_at_depth (loop, loop_depth (aloop) + 1))
     if ((!ref->stored || !bitmap_bit_p (ref->stored, aloop->num))
-       && ref_indep_loop_p (aloop, ref))
+       && ref_indep_loop_p (aloop, ref, loop))
       return aloop;
 
-  if (ref_indep_loop_p (loop, ref))
+  if (ref_indep_loop_p (loop, ref, loop))
     return loop;
   else
     return NULL;
@@ -2109,17 +2109,23 @@ record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p)
     loop = loop_outer (loop);
 }
 
-/* Returns true if REF in REF_LOOP is independent on all other memory
-   references in LOOP.  */
+/* Returns true if REF is independent on all other memory
+   references in LOOP.  REF_LOOP is where REF is accessed, SAFELEN is the
+   safelen to apply.  */
 
 static bool
-ref_indep_loop_p_1 (int safelen, struct loop *loop,
-                   im_mem_ref *ref, bool stored_p)
+ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref,
+                   bool stored_p, struct loop *ref_loop)
 {
+  stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
+
+  if (loop->safelen > safelen
+      /* Check that REF is accessed inside LOOP.  */
+      && (loop == ref_loop || flow_loop_nested_p (loop, ref_loop)))
+    safelen = loop->safelen;
+
+  bool indep_p = true;
   bitmap refs_to_check;
-  unsigned i;
-  bitmap_iterator bi;
-  im_mem_ref *aref;
 
   if (stored_p)
     refs_to_check = &memory_accesses.refs_in_loop[loop->num];
@@ -2127,9 +2133,8 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop,
     refs_to_check = &memory_accesses.refs_stored_in_loop[loop->num];
 
   if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID))
-    return false;
-
-  if (safelen > 1)
+    indep_p = false;
+  else if (safelen > 1)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
@@ -2138,47 +2143,45 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop,
          print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
          fprintf (dump_file, "\n");
        }
+
+      /* Avoid caching here as safelen depends on context and refs
+         are shared between different contexts.  */
       return true;
     }
-
-  EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi)
+  else
     {
-      aref = memory_accesses.refs_list[i];
-      if (!refs_independent_p (ref, aref))
+      if (bitmap_bit_p (&ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
+       return true;
+      if (bitmap_bit_p (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
        return false;
-    }
-
-  return true;
-}
-
-/* Returns true if REF in REF_LOOP is independent on all other memory
-   references in LOOP.  Wrapper over ref_indep_loop_p_1, caching its
-   results.  */
-
-static bool
-ref_indep_loop_p_2 (int safelen, struct loop *loop,
-                   im_mem_ref *ref, bool stored_p)
-{
-  stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
 
-  if (bitmap_bit_p (&ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
-    return true;
-  if (bitmap_bit_p (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
-    return false;
-
-  if (loop->safelen > safelen)
-    safelen = loop->safelen;
+      struct loop *inner = loop->inner;
+      while (inner)
+       {
+         if (!ref_indep_loop_p_1 (safelen, inner, ref, stored_p, ref_loop))
+           {
+             indep_p = false;
+             break;
+           }
+         inner = inner->next;
+       }
 
-  struct loop *inner = loop->inner;
-  while (inner)
-    {
-      if (!ref_indep_loop_p_2 (safelen, inner, ref, stored_p))
-       return false;
-      inner = inner->next;
+      if (indep_p)
+       {
+         unsigned i;
+         bitmap_iterator bi;
+         EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi)
+           {
+             im_mem_ref *aref = memory_accesses.refs_list[i];
+             if (!refs_independent_p (ref, aref))
+               {
+                 indep_p = false;
+                 break;
+               }
+           }
+       }
     }
 
-  bool indep_p = ref_indep_loop_p_1 (safelen, loop, ref, stored_p);
-
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "Querying dependencies of ref %u in loop %d: %s\n",
             ref->id, loop->num, indep_p ? "independent" : "dependent");
@@ -2209,14 +2212,14 @@ ref_indep_loop_p_2 (int safelen, struct loop *loop,
 }
 
 /* Returns true if REF is independent on all other memory references in
-   LOOP.  */
+   LOOP.  REF_LOOP is the loop where REF is accessed.  */
 
 static bool
-ref_indep_loop_p (struct loop *loop, im_mem_ref *ref)
+ref_indep_loop_p (struct loop *loop, im_mem_ref *ref, struct loop *ref_loop)
 {
   gcc_checking_assert (MEM_ANALYZABLE (ref));
 
-  return ref_indep_loop_p_2 (0, loop, ref, false);
+  return ref_indep_loop_p_1 (0, loop, ref, false, ref_loop);
 }
 
 /* Returns true if we can perform store motion of REF from LOOP.  */
@@ -2252,7 +2255,7 @@ can_sm_ref_p (struct loop *loop, im_mem_ref *ref)
 
   /* And it must be independent on all other memory references
      in LOOP.  */
-  if (!ref_indep_loop_p (loop, ref))
+  if (!ref_indep_loop_p (loop, ref, loop))
     return false;
 
   return true;