mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
e8028ecdd0
commit
1a7de2015d
|
|
@ -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>
|
2012-10-23 Terry Guo <terry.guo@arm.com>
|
||||||
|
|
||||||
PR target/55019
|
PR target/55019
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,7 @@ extern struct loop *loopify (edge, edge,
|
||||||
struct loop * loop_version (struct loop *, void *,
|
struct loop * loop_version (struct loop *, void *,
|
||||||
basic_block *, unsigned, unsigned, unsigned, bool);
|
basic_block *, unsigned, unsigned, unsigned, bool);
|
||||||
extern bool remove_path (edge);
|
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);
|
extern void scale_loop_frequencies (struct loop *, int, int);
|
||||||
|
|
||||||
/* Induction variable analysis. */
|
/* Induction variable analysis. */
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ static bool rpe_enum_p (const_basic_block, const void *);
|
||||||
static int find_path (edge, basic_block **);
|
static int find_path (edge, basic_block **);
|
||||||
static void fix_loop_placements (struct loop *, bool *);
|
static void fix_loop_placements (struct loop *, bool *);
|
||||||
static bool fix_bb_placement (basic_block);
|
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. */
|
/* Checks whether basic block BB is dominated by DATA. */
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -159,11 +159,15 @@ fix_loop_placement (struct loop *loop)
|
||||||
successors we consider edges coming out of the loops.
|
successors we consider edges coming out of the loops.
|
||||||
|
|
||||||
If the changes may invalidate the information about irreducible regions,
|
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
|
static void
|
||||||
fix_bb_placements (basic_block from,
|
fix_bb_placements (basic_block from,
|
||||||
bool *irred_invalidated)
|
bool *irred_invalidated,
|
||||||
|
bitmap loop_closed_ssa_invalidated)
|
||||||
{
|
{
|
||||||
sbitmap in_queue;
|
sbitmap in_queue;
|
||||||
basic_block *queue, *qtop, *qbeg, *qend;
|
basic_block *queue, *qtop, *qbeg, *qend;
|
||||||
|
|
@ -218,6 +222,8 @@ fix_bb_placements (basic_block from,
|
||||||
/* Ordinary basic block. */
|
/* Ordinary basic block. */
|
||||||
if (!fix_bb_placement (from))
|
if (!fix_bb_placement (from))
|
||||||
continue;
|
continue;
|
||||||
|
if (loop_closed_ssa_invalidated)
|
||||||
|
bitmap_set_bit (loop_closed_ssa_invalidated, from->index);
|
||||||
target_loop = from->loop_father;
|
target_loop = from->loop_father;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,7 +318,7 @@ remove_path (edge e)
|
||||||
{
|
{
|
||||||
f = loop_outer (l);
|
f = loop_outer (l);
|
||||||
if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest))
|
if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest))
|
||||||
unloop (l, &irred_invalidated);
|
unloop (l, &irred_invalidated, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Identify the path. */
|
/* Identify the path. */
|
||||||
|
|
@ -385,7 +391,7 @@ remove_path (edge e)
|
||||||
|
|
||||||
/* Fix placements of basic blocks inside loops and the placement of
|
/* Fix placements of basic blocks inside loops and the placement of
|
||||||
loops in the loop tree. */
|
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);
|
fix_loop_placements (from->loop_father, &irred_invalidated);
|
||||||
|
|
||||||
if (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.
|
have no successor, which caller is expected to fix somehow.
|
||||||
|
|
||||||
If this may cause the information about irreducible regions to become
|
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
|
void
|
||||||
unloop (struct loop *loop, bool *irred_invalidated)
|
unloop (struct loop *loop, bool *irred_invalidated,
|
||||||
|
bitmap loop_closed_ssa_invalidated)
|
||||||
{
|
{
|
||||||
basic_block *body;
|
basic_block *body;
|
||||||
struct loop *ploop;
|
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
|
/* 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
|
there is an irreducible region inside the cancelled loop, the flags will
|
||||||
be still correct. */
|
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
|
/* 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
|
to the loop. So call fix_bb_placements to fix up the placement
|
||||||
of the preheader and (possibly) of its predecessors. */
|
of the preheader and (possibly) of its predecessors. */
|
||||||
fix_bb_placements (loop_preheader_edge (loop)->src,
|
fix_bb_placements (loop_preheader_edge (loop)->src,
|
||||||
irred_invalidated);
|
irred_invalidated, NULL);
|
||||||
loop = outer;
|
loop = outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2012-10-23 Terry Guo <terry.guo@arm.com>
|
||||||
|
|
||||||
PR target/55019
|
PR target/55019
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -390,13 +390,16 @@ loop_edge_to_cancel (struct loop *loop)
|
||||||
EXIT is the exit of the loop that should be eliminated.
|
EXIT is the exit of the loop that should be eliminated.
|
||||||
IRRED_INVALIDATED is used to bookkeep if information about
|
IRRED_INVALIDATED is used to bookkeep if information about
|
||||||
irreducible regions may become invalid as a result
|
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
|
static bool
|
||||||
try_unroll_loop_completely (struct loop *loop,
|
try_unroll_loop_completely (struct loop *loop,
|
||||||
edge exit, tree niter,
|
edge exit, tree niter,
|
||||||
enum unroll_level ul,
|
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;
|
unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
|
||||||
gimple cond;
|
gimple cond;
|
||||||
|
|
@ -562,7 +565,7 @@ try_unroll_loop_completely (struct loop *loop,
|
||||||
locus = latch_edge->goto_locus;
|
locus = latch_edge->goto_locus;
|
||||||
|
|
||||||
/* Unloop destroys the latch edge. */
|
/* 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
|
/* Create new basic block for the latch edge destination and wire
|
||||||
it in. */
|
it in. */
|
||||||
|
|
@ -615,7 +618,8 @@ static bool
|
||||||
canonicalize_loop_induction_variables (struct loop *loop,
|
canonicalize_loop_induction_variables (struct loop *loop,
|
||||||
bool create_iv, enum unroll_level ul,
|
bool create_iv, enum unroll_level ul,
|
||||||
bool try_eval,
|
bool try_eval,
|
||||||
bool *irred_invalidated)
|
bool *irred_invalidated,
|
||||||
|
bitmap loop_closed_ssa_invalidated)
|
||||||
{
|
{
|
||||||
edge exit = NULL;
|
edge exit = NULL;
|
||||||
tree niter;
|
tree niter;
|
||||||
|
|
@ -663,7 +667,8 @@ canonicalize_loop_induction_variables (struct loop *loop,
|
||||||
(int)max_loop_iterations_int (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;
|
return true;
|
||||||
|
|
||||||
if (create_iv
|
if (create_iv
|
||||||
|
|
@ -683,13 +688,15 @@ canonicalize_induction_variables (void)
|
||||||
struct loop *loop;
|
struct loop *loop;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
bool irred_invalidated = false;
|
bool irred_invalidated = false;
|
||||||
|
bitmap loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
|
||||||
|
|
||||||
FOR_EACH_LOOP (li, loop, 0)
|
FOR_EACH_LOOP (li, loop, 0)
|
||||||
{
|
{
|
||||||
changed |= canonicalize_loop_induction_variables (loop,
|
changed |= canonicalize_loop_induction_variables (loop,
|
||||||
true, UL_SINGLE_ITER,
|
true, UL_SINGLE_ITER,
|
||||||
true,
|
true,
|
||||||
&irred_invalidated);
|
&irred_invalidated,
|
||||||
|
loop_closed_ssa_invalidated);
|
||||||
}
|
}
|
||||||
gcc_assert (!need_ssa_update_p (cfun));
|
gcc_assert (!need_ssa_update_p (cfun));
|
||||||
|
|
||||||
|
|
@ -701,6 +708,13 @@ canonicalize_induction_variables (void)
|
||||||
evaluation could reveal new information. */
|
evaluation could reveal new information. */
|
||||||
scev_reset ();
|
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)
|
if (changed)
|
||||||
return TODO_cleanup_cfg;
|
return TODO_cleanup_cfg;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -794,11 +808,15 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
|
||||||
bool changed;
|
bool changed;
|
||||||
enum unroll_level ul;
|
enum unroll_level ul;
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
|
bool irred_invalidated = false;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
bool irred_invalidated = false;
|
|
||||||
changed = 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)
|
FOR_EACH_LOOP (li, loop, 0)
|
||||||
{
|
{
|
||||||
|
|
@ -812,9 +830,9 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
|
||||||
else
|
else
|
||||||
ul = UL_NO_GROWTH;
|
ul = UL_NO_GROWTH;
|
||||||
|
|
||||||
if (canonicalize_loop_induction_variables (loop, false, ul,
|
if (canonicalize_loop_induction_variables
|
||||||
!flag_tree_loop_ivcanon,
|
(loop, false, ul, !flag_tree_loop_ivcanon,
|
||||||
&irred_invalidated))
|
&irred_invalidated, loop_closed_ssa_invalidated))
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
/* If we'll continue unrolling, we need to propagate constants
|
/* 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;
|
struct loop **iter;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (irred_invalidated
|
/* We can not use TODO_update_ssa_no_phi because VOPS gets confused. */
|
||||||
&& loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
|
|
||||||
mark_irreducible_loops ();
|
|
||||||
|
|
||||||
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. */
|
/* Propagate the constants within the new basic blocks. */
|
||||||
FOR_EACH_VEC_ELT (loop_p, father_stack, i, iter)
|
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
|
/* Clean up the information about numbers of iterations, since
|
||||||
complete unrolling might have invalidated it. */
|
complete unrolling might have invalidated it. */
|
||||||
scev_reset ();
|
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
|
while (changed
|
||||||
&& ++iteration <= PARAM_VALUE (PARAM_MAX_UNROLL_ITERATIONS));
|
&& ++iteration <= PARAM_VALUE (PARAM_MAX_UNROLL_ITERATIONS));
|
||||||
|
|
||||||
VEC_free (loop_p, stack, father_stack);
|
VEC_free (loop_p, stack, father_stack);
|
||||||
|
|
||||||
|
if (irred_invalidated
|
||||||
|
&& loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
|
||||||
|
mark_irreducible_loops ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue