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
This commit is contained in:
Jan Hubicka 2012-10-23 11:57:36 +02:00 committed by Jan Hubicka
parent e8028ecdd0
commit 1a7de2015d
6 changed files with 122 additions and 24 deletions

View 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

View 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. */

View 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;
}
}

View 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

View File

@ -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

View 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;
}