fix PR68693: Check for loop structure when extending the SCoP
authorAditya Kumar <aditya.k7@samsung.com>
Fri, 4 Dec 2015 21:36:55 +0000 (21:36 +0000)
committerSebastian Pop <spop@gcc.gnu.org>
Fri, 4 Dec 2015 21:36:55 +0000 (21:36 +0000)
The check for dominance while extending the scop assumed that
multiple successors meant a loop which is not true in case of
conditionals around the loop.

Improved pretty printers for better debugging.

PR tree-optimization/68693
        * graphite-scop-detection.c (dot_all_sese): New
        (dot_all_scops_1): Renamed to dot_all_sese.
        (dot_all_scops): Removed.
        (dot_sese): New.
        (dot_cfg): New.
        (scop_detection::get_nearest_dom_with_single_entry): Check that preds are from different loop levels.
        (scop_detection::get_nearest_pdom_with_single_exit): Check that succs are from different loop levels.
        (scop_detection::print_sese): Inlined.
        (scop_detection::print_edge): New.
        (scop_detection::merge_sese): Added dumps.
        * graphite.h: Add declarations.

gcc/testsuite/ChangeLog:

        * gfortran.dg/graphite/pr68693.f90: New test.

Co-Authored-By: Sebastian Pop <s.pop@samsung.com>
From-SVN: r231309

gcc/ChangeLog
gcc/graphite-scop-detection.c
gcc/graphite.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/graphite/pr68693.f90 [new file with mode: 0644]

index 06e0d7b6b649cff88210032d639cea7e7e2970b0..4223a1ecb5bf6dd8b1a2675364315ab0df71497e 100644 (file)
@@ -1,3 +1,21 @@
+2015-12-04  Aditya Kumar  <aditya.k7@samsung.com>
+           Sebastian Pop  <s.pop@samsung.com>
+
+       PR tree-optimization/68693
+       * graphite-scop-detection.c (dot_all_sese): New
+       (dot_all_scops_1): Renamed to dot_all_sese.
+       (dot_all_scops): Removed.
+       (dot_sese): New.
+       (dot_cfg): New.
+       (scop_detection::get_nearest_dom_with_single_entry): Check that
+       preds are from different loop levels.
+       (scop_detection::get_nearest_pdom_with_single_exit): Check that
+       succs are from different loop levels.
+       (scop_detection::print_sese): Inlined.
+       (scop_detection::print_edge): New.
+       (scop_detection::merge_sese): Added dumps.
+       * graphite.h: Add declarations.
+
 2015-12-04  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * config/aarch64/aarch64.md (add<mode>3_pluslong): Add register
index 2f4231a45829589159330e317bf19e36a64be059..729a5fd5588e7f501edabeb8c04caf16e44a5970 100644 (file)
@@ -98,22 +98,16 @@ public:
    - "()" around the node number denotes the entry or the
      exit nodes of the SCOP.  These are not part of SCoP.  */
 
-static void
-dot_all_scops_1 (FILE *file, vec<scop_p> scops)
+DEBUG_FUNCTION void
+dot_all_sese (FILE *file, vec<sese_l>& scops)
 {
-  basic_block bb;
-  edge e;
-  edge_iterator ei;
-  scop_p scop;
-  const char *color;
-  int i;
-
   /* Disable debugging while printing graph.  */
   int tmp_dump_flags = dump_flags;
   dump_flags = 0;
 
   fprintf (file, "digraph all {\n");
 
+  basic_block bb;
   FOR_ALL_BB_FN (bb, cfun)
     {
       int part_of_scop = false;
@@ -126,12 +120,15 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops)
       fprintf (file, "CELLSPACING=\"0\">\n");
 
       /* Select color for SCoP.  */
-      FOR_EACH_VEC_ELT (scops, i, scop)
+      sese_l *region;
+      int i;
+      FOR_EACH_VEC_ELT (scops, i, region)
        {
-         sese_l region = scop->scop_info->region;
-         if (bb_in_sese_p (bb, region) || (region.exit->dest == bb)
-             || (region.entry->dest == bb))
+         bool sese_in_region = bb_in_sese_p (bb, *region);
+         if (sese_in_region || (region->exit->dest == bb)
+             || (region->entry->dest == bb))
            {
+             const char *color;
              switch (i % 17)
                {
                case 0: /* red */
@@ -192,21 +189,21 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops)
              fprintf (file, "    <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">",
                       color);
 
-             if (!bb_in_sese_p (bb, region))
+             if (!sese_in_region)
                fprintf (file, " (");
 
-             if (bb == region.entry->dest && bb == region.exit->dest)
+             if (bb == region->entry->dest && bb == region->exit->dest)
                fprintf (file, " %d*# ", bb->index);
-             else if (bb == region.entry->dest)
+             else if (bb == region->entry->dest)
                fprintf (file, " %d* ", bb->index);
-             else if (bb == region.exit->dest)
+             else if (bb == region->exit->dest)
                fprintf (file, " %d# ", bb->index);
              else
                fprintf (file, " %d ", bb->index);
 
              fprintf (file, "{lp_%d}", bb->loop_father->num);
 
-             if (!bb_in_sese_p (bb, region))
+             if (!sese_in_region)
                fprintf (file, ")");
 
              fprintf (file, "</TD></TR>\n");
@@ -225,6 +222,8 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops)
 
     FOR_ALL_BB_FN (bb, cfun)
       {
+       edge e;
+       edge_iterator ei;
        FOR_EACH_EDGE (e, ei, bb->succs)
          fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
       }
@@ -235,52 +234,29 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops)
   dump_flags = tmp_dump_flags;
 }
 
-/* Display all SCoPs using dotty.  */
-
-DEBUG_FUNCTION void
-dot_all_scops (vec<scop_p> scops)
-{
-  /* When debugging, enable the following code.  This cannot be used
-     in production compilers because it calls "system".  */
-#if 0
-  int x;
-  FILE *stream = fopen ("/tmp/allscops.dot", "w");
-  gcc_assert (stream);
-
-  dot_all_scops_1 (stream, scops);
-  fclose (stream);
-
-  x = system ("dotty /tmp/allscops.dot &");
-#else
-  dot_all_scops_1 (stderr, scops);
-#endif
-}
-
-/* Display all SCoPs using dotty.  */
+/* Display SCoP on stderr.  */
 
 DEBUG_FUNCTION void
-dot_scop (scop_p scop)
+dot_sese (sese_l& scop)
 {
-  auto_vec<scop_p, 1> scops;
+  vec<sese_l> scops;
+  scops.create (1);
 
   if (scop)
     scops.safe_push (scop);
 
-  /* When debugging, enable the following code.  This cannot be used
-     in production compilers because it calls "system".  */
-#if 0
-  {
-    int x;
-    FILE *stream = fopen ("/tmp/allscops.dot", "w");
-    gcc_assert (stream);
+  dot_all_sese (stderr, scops);
 
-    dot_all_scops_1 (stream, scops);
-    fclose (stream);
-    x = system ("dotty /tmp/allscops.dot &");
-  }
-#else
-  dot_all_scops_1 (stderr, scops);
-#endif
+  scops.release ();
+}
+
+DEBUG_FUNCTION void
+dot_cfg ()
+{
+  vec<sese_l> scops;
+  scops.create (1);
+  dot_all_sese (stderr, scops);
+  scops.release ();
 }
 
 /* Return true if BB is empty, contains only DEBUG_INSNs.  */
@@ -552,9 +528,20 @@ public:
 
   static edge get_nearest_pdom_with_single_exit (basic_block dom);
 
-  /* Print S to FILE.  */
 
-  static void print_sese (FILE *file, sese_l s);
+  /* Pretty printers.  */
+
+  static void print_edge (FILE *file, const_edge e)
+  {
+    fprintf (file, "edge (bb_%d, bb_%d)", e->src->index, e->dest->index);
+  }
+
+  static void print_sese (FILE *file, sese_l s)
+  {
+    fprintf (file, "(entry_"); print_edge (file, s.entry);
+    fprintf (file, ", exit_"); print_edge (file, s.exit);
+    fprintf (file, ")\n");
+  }
 
   /* Merge scops at same loop depth and returns the new sese.
      Returns a new SESE when merge was successful, INVALID_SESE otherwise.  */
@@ -717,9 +704,14 @@ scop_detection::get_nearest_dom_with_single_entry (basic_block dom)
     {
       edge e1 = (*dom->preds)[0];
       edge e2 = (*dom->preds)[1];
-      if (dominated_by_p (CDI_DOMINATORS, e2->src, e1->src))
+      loop_p l = dom->loop_father;
+      loop_p l1 = e1->src->loop_father;
+      loop_p l2 = e2->src->loop_father;
+      if (l != l1
+         && dominated_by_p (CDI_DOMINATORS, e2->src, e1->src))
        return e1;
-      if (dominated_by_p (CDI_DOMINATORS, e1->src, e2->src))
+      if (l != l2
+         && dominated_by_p (CDI_DOMINATORS, e1->src, e2->src))
        return e2;
     }
 
@@ -738,39 +730,35 @@ scop_detection::get_nearest_dom_with_single_entry (basic_block dom)
    back-loop the back-edge is not counted.  */
 
 edge
-scop_detection::get_nearest_pdom_with_single_exit (basic_block dom)
+scop_detection::get_nearest_pdom_with_single_exit (basic_block pdom)
 {
-  if (!dom->succs)
+  if (!pdom->succs)
     return NULL;
-  if (dom->succs->length () == 2)
+  if (pdom->succs->length () == 2)
     {
-      edge e1 = (*dom->succs)[0];
-      edge e2 = (*dom->succs)[1];
-      if (dominated_by_p (CDI_POST_DOMINATORS, e2->dest, e1->dest))
+      edge e1 = (*pdom->succs)[0];
+      edge e2 = (*pdom->succs)[1];
+      loop_p l = pdom->loop_father;
+      loop_p l1 = e1->dest->loop_father;
+      loop_p l2 = e2->dest->loop_father;
+      if (l != l1
+         && dominated_by_p (CDI_POST_DOMINATORS, e2->dest, e1->dest))
        return e1;
-      if (dominated_by_p (CDI_POST_DOMINATORS, e1->dest, e2->dest))
+      if (l != l2
+         && dominated_by_p (CDI_POST_DOMINATORS, e1->dest, e2->dest))
        return e2;
     }
 
-  while (dom->succs->length () != 1)
+  while (pdom->succs->length () != 1)
     {
-      if (dom->succs->length () < 1)
+      if (pdom->succs->length () < 1)
        return NULL;
-      dom = get_immediate_dominator (CDI_POST_DOMINATORS, dom);
-      if (!dom->succs)
+      pdom = get_immediate_dominator (CDI_POST_DOMINATORS, pdom);
+      if (!pdom->succs)
        return NULL;
     }
-  return (*dom->succs)[0];
-}
-
-/* Print S to FILE.  */
 
-void
-scop_detection::print_sese (FILE *file, sese_l s)
-{
-  fprintf (file, "(entry_edge (bb_%d, bb_%d), exit_edge (bb_%d, bb_%d))\n",
-           s.entry->src->index, s.entry->dest->index,
-           s.exit->src->index, s.exit->dest->index);
+  return (*pdom->succs)[0];
 }
 
 /* Merge scops at same loop depth and returns the new sese.
@@ -815,6 +803,9 @@ scop_detection::merge_sese (sese_l first, sese_l second) const
 
   sese_l combined (entry, exit);
 
+  DEBUG_PRINT (dp << "checking combined sese: ";
+              print_sese (dump_file, combined));
+
   /* FIXME: We could iterate to find the dom which dominates pdom, and pdom
      which post-dominates dom, until it stabilizes.  Also, ENTRY->SRC and
      EXIT->DEST should be in the same loop nest.  */
index 30272bbc46cb32723d986008d667218058add7f5..c7589baef4fa282dc5e56fb418009012203e53f6 100644 (file)
@@ -465,7 +465,7 @@ extern bool build_poly_scop (scop_p);
 extern bool graphite_regenerate_ast_isl (scop_p);
 
 extern void build_scops (vec<scop_p> *);
-extern void dot_all_scops (vec<scop_p>);
-extern void dot_scop (scop_p);
-
+extern void dot_all_sese (FILE *, vec<sese_l> &);
+extern void dot_sese (sese_l &);
+extern void dot_cfg ();
 #endif
index ebeab6b423c48070a79ea17230790ed9342c3850..312224800bed39eb47cb9a0c9f54099986ef38b0 100644 (file)
@@ -1,3 +1,9 @@
+2015-12-04  Aditya Kumar  <aditya.k7@samsung.com>
+           Sebastian Pop  <s.pop@samsung.com>
+
+       PR tree-optimization/68693
+       * gfortran.dg/graphite/pr68693.f90: New test.
+
 2015-12-04  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * gcc.c-torture/compile/20151204.c: New.
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr68693.f90 b/gcc/testsuite/gfortran.dg/graphite/pr68693.f90
new file mode 100644 (file)
index 0000000..24b85e3
--- /dev/null
@@ -0,0 +1,35 @@
+! { dg-options "-floop-nest-optimize -O2" }
+MODULE dbcsr_index_operations
+  INTERFACE dbcsr_build_row_index
+  END INTERFACE
+CONTAINS
+  SUBROUTINE merge_index_arrays (new_row_i, new_col_i, new_blk_p, new_size,&
+       old_row_i, old_col_i, old_blk_p, old_size,&
+       add_ip, add_size, new_blk_d, old_blk_d,&
+       added_size_offset, added_sizes, added_size, added_nblks, error)
+    INTEGER, DIMENSION(new_size), &
+      INTENT(OUT)                            :: new_blk_p, new_col_i, &
+                                                new_row_i
+    INTEGER, INTENT(IN)                      :: old_size
+    INTEGER, DIMENSION(old_size), INTENT(IN) :: old_blk_p, old_col_i, &
+                                                old_row_i
+    INTEGER, DIMENSION(new_size), &
+      INTENT(OUT), OPTIONAL                  :: new_blk_d
+    INTEGER, DIMENSION(old_size), &
+      INTENT(IN), OPTIONAL                   :: old_blk_d
+    INTEGER, DIMENSION(:), INTENT(IN), &
+      OPTIONAL                               :: added_sizes
+    INTEGER, INTENT(OUT), OPTIONAL           :: added_size, added_nblks
+    LOGICAL                                  :: multidata
+    IF (add_size .GT. 0) THEN
+       IF (old_size .EQ. 0) THEN
+          IF (PRESENT (added_size)) added_size = SUM (added_sizes)
+       ENDIF
+    ELSE
+       new_row_i(1:old_size) = old_row_i(1:old_size)
+       new_col_i(1:old_size) = old_col_i(1:old_size)
+       new_blk_p(1:old_size) = old_blk_p(1:old_size)
+       IF (multidata) new_blk_d(1:old_size) = old_blk_d(1:old_size)
+    ENDIF
+  END SUBROUTINE merge_index_arrays
+END MODULE dbcsr_index_operations