]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/54967 (ICE in check_loop_closed_ssa_use, at tree-ssa-loop...
authorJan Hubicka <jh@suse.cz>
Tue, 23 Oct 2012 09:57:36 +0000 (11:57 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 23 Oct 2012 09:57:36 +0000 (09:57 +0000)
PR middle-end/54967
* cfgloopmanip.c (fix_bb_placements): Add loop_closed_ssa_invalidated;
track basic blocks that moved out of their loops.
(unloop): Likewise.
(remove_path): Update.
(fix_loop_placements): Update.
* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Add
loop_closed_ssa_invalidated parameter; pass it around.
(canonicalize_loop_induction_variables): Update loop closed
SSA form if needed.
(tree_unroll_loops_completely): Likewise; do irred update out of
the outer loop; verify that SSA form is closed.
* cfgloop.h (unrloop): Update.

* gfortran.dg/pr54967.f90: New testcase.

From-SVN: r192709

gcc/ChangeLog
gcc/cfgloop.h
gcc/cfgloopmanip.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr54967.f90 [new file with mode: 0644]
gcc/tree-ssa-loop-ivcanon.c

index 236464f4dc1dc438c66e88bb377811b26934288d..d9c294eb2ab451aa897480e2d67b951ffea1e0c5 100644 (file)
@@ -1,3 +1,19 @@
+2012-10-23  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/54967
+       * cfgloopmanip.c (fix_bb_placements): Add loop_closed_ssa_invalidated;
+       track basic blocks that moved out of their loops.
+       (unloop): Likewise.
+       (remove_path): Update.
+       (fix_loop_placements): Update.
+       * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Add
+       loop_closed_ssa_invalidated parameter; pass it around.
+       (canonicalize_loop_induction_variables): Update loop closed
+       SSA form if needed.
+       (tree_unroll_loops_completely): Likewise; do irred update out of
+       the outer loop; verify that SSA form is closed.
+       * cfgloop.h (unrloop): Update.
+
 2012-10-23  Terry Guo  <terry.guo@arm.com>
 
        PR target/55019
index a48550445a37e3cf4665e907adeecd4fd00f0814..94ad6372d2848e7808b3bb6424f6bd30741fa6a1 100644 (file)
@@ -321,7 +321,7 @@ extern struct loop *loopify (edge, edge,
 struct loop * loop_version (struct loop *, void *,
                            basic_block *, unsigned, unsigned, unsigned, bool);
 extern bool remove_path (edge);
-extern void unloop (struct loop *, bool *);
+extern void unloop (struct loop *, bool *, bitmap);
 extern void scale_loop_frequencies (struct loop *, int, int);
 
 /* Induction variable analysis.  */
index 97a90bbff1d400f03cd047528c38ebc89074ccc1..eae68ca43c79b9089d5ccf1c738531f38b432f85 100644 (file)
@@ -36,7 +36,7 @@ static bool rpe_enum_p (const_basic_block, const void *);
 static int find_path (edge, basic_block **);
 static void fix_loop_placements (struct loop *, bool *);
 static bool fix_bb_placement (basic_block);
-static void fix_bb_placements (basic_block, bool *);
+static void fix_bb_placements (basic_block, bool *, bitmap);
 
 /* Checks whether basic block BB is dominated by DATA.  */
 static bool
@@ -159,11 +159,15 @@ fix_loop_placement (struct loop *loop)
    successors we consider edges coming out of the loops.
 
    If the changes may invalidate the information about irreducible regions,
-   IRRED_INVALIDATED is set to true.  */
+   IRRED_INVALIDATED is set to true.  
+
+   If LOOP_CLOSED_SSA_INVLIDATED is non-zero then all basic blocks with
+   changed loop_father are collected there. */
 
 static void
 fix_bb_placements (basic_block from,
-                  bool *irred_invalidated)
+                  bool *irred_invalidated,
+                  bitmap loop_closed_ssa_invalidated)
 {
   sbitmap in_queue;
   basic_block *queue, *qtop, *qbeg, *qend;
@@ -218,6 +222,8 @@ fix_bb_placements (basic_block from,
          /* Ordinary basic block.  */
          if (!fix_bb_placement (from))
            continue;
+         if (loop_closed_ssa_invalidated)
+           bitmap_set_bit (loop_closed_ssa_invalidated, from->index);
          target_loop = from->loop_father;
        }
 
@@ -312,7 +318,7 @@ remove_path (edge e)
     {
       f = loop_outer (l);
       if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest))
-        unloop (l, &irred_invalidated);
+        unloop (l, &irred_invalidated, NULL);
     }
 
   /* Identify the path.  */
@@ -385,7 +391,7 @@ remove_path (edge e)
 
   /* Fix placements of basic blocks inside loops and the placement of
      loops in the loop tree.  */
-  fix_bb_placements (from, &irred_invalidated);
+  fix_bb_placements (from, &irred_invalidated, NULL);
   fix_loop_placements (from->loop_father, &irred_invalidated);
 
   if (irred_invalidated
@@ -892,10 +898,14 @@ loopify (edge latch_edge, edge header_edge,
    have no successor, which caller is expected to fix somehow.
 
    If this may cause the information about irreducible regions to become
-   invalid, IRRED_INVALIDATED is set to true.  */
+   invalid, IRRED_INVALIDATED is set to true.  
+
+   LOOP_CLOSED_SSA_INVALIDATED, if non-NULL, is a bitmap where we store
+   basic blocks that had non-trivial update on their loop_father.*/
 
 void
-unloop (struct loop *loop, bool *irred_invalidated)
+unloop (struct loop *loop, bool *irred_invalidated,
+       bitmap loop_closed_ssa_invalidated)
 {
   basic_block *body;
   struct loop *ploop;
@@ -937,7 +947,7 @@ unloop (struct loop *loop, bool *irred_invalidated)
   /* We do not pass IRRED_INVALIDATED to fix_bb_placements here, as even if
      there is an irreducible region inside the cancelled loop, the flags will
      be still correct.  */
-  fix_bb_placements (latch, &dummy);
+  fix_bb_placements (latch, &dummy, loop_closed_ssa_invalidated);
 }
 
 /* Fix placement of superloops of LOOP inside loop tree, i.e. ensure that
@@ -965,7 +975,7 @@ fix_loop_placements (struct loop *loop, bool *irred_invalidated)
         to the loop.  So call fix_bb_placements to fix up the placement
         of the preheader and (possibly) of its predecessors.  */
       fix_bb_placements (loop_preheader_edge (loop)->src,
-                        irred_invalidated);
+                        irred_invalidated, NULL);
       loop = outer;
     }
 }
index 16e6dd6b4277ad72986229a53e9aa32a68cb52cc..7daf70e366d55969cb13689409ad39e9fd88fc24 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-23  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/54967
+       * gfortran.dg/pr54967.f90: New testcase.
+
 2012-10-23  Terry Guo  <terry.guo@arm.com>
 
        PR target/55019
diff --git a/gcc/testsuite/gfortran.dg/pr54967.f90 b/gcc/testsuite/gfortran.dg/pr54967.f90
new file mode 100644 (file)
index 0000000..f674e3e
--- /dev/null
@@ -0,0 +1,36 @@
+ SUBROUTINE calc_S_derivs()
+    INTEGER, DIMENSION(6, 2)      :: c_map_mat
+    INTEGER, DIMENSION(:), POINTER:: C_mat
+    DO j=1,3
+       DO m=j,3
+          n=n+1
+          c_map_mat(n,1)=j
+          IF(m==j)CYCLE
+          c_map_mat(n,2)=m
+       END DO
+    END DO
+    DO m=1,6
+       DO j=1,2
+          IF(c_map_mat(m,j)==0)CYCLE
+          CALL foo(C_mat(c_map_mat(m,j))) 
+       END DO
+    END DO
+  END SUBROUTINE calc_S_derivs
+ SUBROUTINE calc_S_derivs()
+    INTEGER, DIMENSION(6, 2)      :: c_map_mat
+    INTEGER, DIMENSION(:), POINTER:: C_mat
+    DO j=1,3
+       DO m=j,3
+          n=n+1
+          c_map_mat(n,1)=j
+          IF(m==j)CYCLE
+          c_map_mat(n,2)=m
+       END DO
+    END DO
+    DO m=1,6
+       DO j=1,2
+          IF(c_map_mat(m,j)==0)CYCLE
+          CALL foo(C_mat(c_map_mat(m,j))) 
+       END DO
+    END DO
+  END SUBROUTINE calc_S_derivs
index 81bf09e9f8ab6a2a778902c495790565a8a1f05d..323045f32eb9f0e3a24331f170a3feac3380e34e 100644 (file)
@@ -390,13 +390,16 @@ loop_edge_to_cancel (struct loop *loop)
    EXIT is the exit of the loop that should be eliminated.  
    IRRED_INVALIDATED is used to bookkeep if information about
    irreducible regions may become invalid as a result
-   of the transformation.  */
+   of the transformation.  
+   LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case
+   when we need to go into loop closed SSA form.  */
 
 static bool
 try_unroll_loop_completely (struct loop *loop,
                            edge exit, tree niter,
                            enum unroll_level ul,
-                           bool *irred_invalidated)
+                           bool *irred_invalidated,
+                           bitmap loop_closed_ssa_invalidated)
 {
   unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
   gimple cond;
@@ -562,7 +565,7 @@ try_unroll_loop_completely (struct loop *loop,
       locus = latch_edge->goto_locus;
 
       /* Unloop destroys the latch edge.  */
-      unloop (loop, irred_invalidated);
+      unloop (loop, irred_invalidated, loop_closed_ssa_invalidated);
 
       /* Create new basic block for the latch edge destination and wire
         it in.  */
@@ -615,7 +618,8 @@ static bool
 canonicalize_loop_induction_variables (struct loop *loop,
                                       bool create_iv, enum unroll_level ul,
                                       bool try_eval,
-                                      bool *irred_invalidated)
+                                      bool *irred_invalidated,
+                                      bitmap loop_closed_ssa_invalidated)
 {
   edge exit = NULL;
   tree niter;
@@ -663,7 +667,8 @@ canonicalize_loop_induction_variables (struct loop *loop,
               (int)max_loop_iterations_int (loop));
     }
 
-  if (try_unroll_loop_completely (loop, exit, niter, ul, irred_invalidated))
+  if (try_unroll_loop_completely (loop, exit, niter, ul, irred_invalidated,
+                                 loop_closed_ssa_invalidated))
     return true;
 
   if (create_iv
@@ -683,13 +688,15 @@ canonicalize_induction_variables (void)
   struct loop *loop;
   bool changed = false;
   bool irred_invalidated = false;
+  bitmap loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
 
   FOR_EACH_LOOP (li, loop, 0)
     {
       changed |= canonicalize_loop_induction_variables (loop,
                                                        true, UL_SINGLE_ITER,
                                                        true,
-                                                       &irred_invalidated);
+                                                       &irred_invalidated,
+                                                       loop_closed_ssa_invalidated);
     }
   gcc_assert (!need_ssa_update_p (cfun));
 
@@ -701,6 +708,13 @@ canonicalize_induction_variables (void)
      evaluation could reveal new information.  */
   scev_reset ();
 
+  if (!bitmap_empty_p (loop_closed_ssa_invalidated))
+    {
+      gcc_checking_assert (loops_state_satisfies_p (LOOP_CLOSED_SSA));
+      rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
+    }
+  BITMAP_FREE (loop_closed_ssa_invalidated);
+
   if (changed)
     return TODO_cleanup_cfg;
   return 0;
@@ -794,11 +808,15 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
   bool changed;
   enum unroll_level ul;
   int iteration = 0;
+  bool irred_invalidated = false;
 
   do
     {
-      bool irred_invalidated = false;
       changed = false;
+      bitmap loop_closed_ssa_invalidated = NULL;
+
+      if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
+       loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
 
       FOR_EACH_LOOP (li, loop, 0)
        {
@@ -812,9 +830,9 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
          else
            ul = UL_NO_GROWTH;
 
-         if (canonicalize_loop_induction_variables (loop, false, ul,
-                                                    !flag_tree_loop_ivcanon,
-                                                    &irred_invalidated))
+         if (canonicalize_loop_induction_variables
+                (loop, false, ul, !flag_tree_loop_ivcanon,
+                 &irred_invalidated, loop_closed_ssa_invalidated))
            {
              changed = true;
              /* If we'll continue unrolling, we need to propagate constants
@@ -834,11 +852,14 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
          struct loop **iter;
          unsigned i;
 
-         if (irred_invalidated
-             && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
-           mark_irreducible_loops ();
+         /* We can not use TODO_update_ssa_no_phi because VOPS gets confused.  */
 
-         update_ssa (TODO_update_ssa);
+         if (loop_closed_ssa_invalidated
+             && !bitmap_empty_p (loop_closed_ssa_invalidated))
+            rewrite_into_loop_closed_ssa (loop_closed_ssa_invalidated,
+                                         TODO_update_ssa);
+         else
+           update_ssa (TODO_update_ssa);
 
          /* Propagate the constants within the new basic blocks.  */
          FOR_EACH_VEC_ELT (loop_p, father_stack, i, iter)
@@ -861,12 +882,22 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
          /* Clean up the information about numbers of iterations, since
             complete unrolling might have invalidated it.  */
          scev_reset ();
+#ifdef ENABLE_CHECKING
+         if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
+           verify_loop_closed_ssa (true);
+#endif
        }
+      if (loop_closed_ssa_invalidated)
+        BITMAP_FREE (loop_closed_ssa_invalidated);
     }
   while (changed
         && ++iteration <= PARAM_VALUE (PARAM_MAX_UNROLL_ITERATIONS));
 
   VEC_free (loop_p, stack, father_stack);
 
+  if (irred_invalidated
+      && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
+    mark_irreducible_loops ();
+
   return 0;
 }