+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
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. */
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
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;
/* 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;
}
{
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. */
/* 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
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;
/* 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
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;
}
}
+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
--- /dev/null
+ 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
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;
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. */
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;
(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
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));
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;
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)
{
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
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)
/* 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;
}