aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2012-10-23 11:57:36 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2012-10-23 09:57:36 +0000
commit1a7de2015dfb81f40015a95be98abe50ad7382f0 (patch)
treedff1e819fae3b996fcd725e178165e8cf066a614 /gcc
parente8028ecdd02be651ec23cfdbc7e31c5b4b198ce1 (diff)
downloadgcc-1a7de2015dfb81f40015a95be98abe50ad7382f0.zip
gcc-1a7de2015dfb81f40015a95be98abe50ad7382f0.tar.gz
gcc-1a7de2015dfb81f40015a95be98abe50ad7382f0.tar.bz2
re PR tree-optimization/54967 (ICE in check_loop_closed_ssa_use, at tree-ssa-loop-manip.c:55)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/cfgloopmanip.c28
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/pr54967.f9036
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c59
6 files changed, 122 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 236464f..d9c294e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index a485504..94ad637 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -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. */
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 97a90bb..eae68ca 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -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;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 16e6dd6..7daf70e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..f674e3e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr54967.f90
@@ -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
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 81bf09e..323045f 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -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;
}