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>
|
||||
|
||||
PR target/55019
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue