Correcting transform_to_exit_first_loop + fix to PR tree-optimization/46886

2012-04-20  Razya Ladelsky  <razya@il.ibm.com>
                 Correcting transform_to_exit_first_loop + fix to
                 PR tree-optimization/46886
                 * tree-parloops.c (transform_to_exit_first_loop):
                 * Remove setting of number of iterations according to
                 * the loop pattern.
                 Duplicate from entry to exit->src instead of
loop->latch.
                 (pallelize_loops): Remove the condition preventing
do-while loops.
                 * tree-cfg.c (bool bb_in_region_p): New.
                 (gimple_duplicate_sese_tail): Adjust duplication of the
the subloops.
                 Adjust redirection of the duplicated iteration.

From-SVN: r186667
This commit is contained in:
Razya Ladelsky 2012-04-22 10:36:13 +00:00 committed by Razya Ladelsky
parent bf310e122b
commit 69958396d9
3 changed files with 39 additions and 44 deletions

View File

@ -1,3 +1,12 @@
2012-04-22 Razya Ladelsky <razya@il.ibm.com>
Correcting transform_to_exit_first_loop + fix to PR46886
* tree-parloops.c (transform_to_exit_first_loop): Remove setting of number of iterations according to the loop pattern.
Duplicate from entry to exit->src instead of loop->latch.
(pallelize_loops): Remove the condition preventing do-while loops.
* tree-cfg.c (bool bb_in_region_p): New.
(gimple_duplicate_sese_tail): Adjust duplication of the the subloops.
Adjust redirection of the duplicated iteration.
2012-04-21 Richard Sandiford <rdsandiford@googlemail.com>
PR bootstrap/53021

View File

@ -5595,6 +5595,20 @@ gimple_duplicate_sese_region (edge entry, edge exit,
return true;
}
/* Checks if BB is part of the region defined by N_REGION BBS. */
static bool
bb_part_of_region_p (basic_block bb, basic_block* bbs, unsigned n_region)
{
unsigned int n;
for (n = 0; n < n_region; n++)
{
if (bb == bbs[n])
return true;
}
return false;
}
/* Duplicates REGION consisting of N_REGION blocks. The new blocks
are stored to REGION_COPY in the same order in that they appear
in REGION, if REGION_COPY is not NULL. ENTRY is the entry to
@ -5645,6 +5659,7 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
gimple_stmt_iterator psi;
gimple phi;
tree def;
struct loop *target, *aloop, *cloop;
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
exits[0] = exit;
@ -5655,7 +5670,16 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
initialize_original_copy_tables ();
set_loop_copy (orig_loop, loop);
duplicate_subloops (orig_loop, loop);
target= loop;
for (aloop = orig_loop->inner; aloop; aloop = aloop->next)
{
if (bb_part_of_region_p (aloop->header, region, n_region))
{
cloop = duplicate_loop (aloop, target);
duplicate_subloops (aloop, cloop);
}
}
if (!region_copy)
{
@ -5758,7 +5782,7 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e));
}
}
e = redirect_edge_and_branch (nexits[0], nexits[1]->dest);
e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
PENDING_STMT (e) = NULL;
/* Anything that is outside of the region, but was dominated by something

View File

@ -1481,8 +1481,6 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
gimple phi, nphi, cond_stmt, stmt, cond_nit;
gimple_stmt_iterator gsi;
tree nit_1;
edge exit_1;
tree new_rhs;
split_block_after_labels (loop->header);
orig_header = single_succ (loop->header);
@ -1512,41 +1510,10 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
}
}
/* Setting the condition towards peeling the last iteration:
If the block consisting of the exit condition has the latch as
successor, then the body of the loop is executed before
the exit condition is tested. In such case, moving the
condition to the entry, causes that the loop will iterate
one less iteration (which is the wanted outcome, since we
peel out the last iteration). If the body is executed after
the condition, moving the condition to the entry requires
decrementing one iteration. */
exit_1 = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit);
if (exit_1->dest == loop->latch)
new_rhs = gimple_cond_rhs (cond_stmt);
else
{
new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (gimple_cond_rhs (cond_stmt)),
gimple_cond_rhs (cond_stmt),
build_int_cst (TREE_TYPE (gimple_cond_rhs (cond_stmt)), 1));
if (TREE_CODE (gimple_cond_rhs (cond_stmt)) == SSA_NAME)
{
basic_block preheader;
gimple_stmt_iterator gsi1;
preheader = loop_preheader_edge(loop)->src;
gsi1 = gsi_after_labels (preheader);
new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true,
NULL_TREE,false,GSI_CONTINUE_LINKING);
}
}
gimple_cond_set_rhs (cond_stmt, unshare_expr (new_rhs));
gimple_cond_set_lhs (cond_stmt, unshare_expr (gimple_cond_lhs (cond_stmt)));
bbs = get_loop_body_in_dom_order (loop);
for (n = 0; bbs[n] != loop->latch; n++)
continue;
for (n = 0; bbs[n] != exit->src; n++)
continue;
nbbs = XNEWVEC (basic_block, n);
ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
bbs + 1, n, nbbs);
@ -1557,7 +1524,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
/* Other than reductions, the only gimple reg that should be copied
out of the loop is the control variable. */
exit = single_dom_exit (loop);
control_name = NULL_TREE;
for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); )
{
@ -1574,8 +1541,6 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
PHI_RESULT of this phi is the resulting value of the reduction
variable when exiting the loop. */
exit = single_dom_exit (loop);
if (htab_elements (reduction_list) > 0)
{
struct reduction_info *red;
@ -2187,10 +2152,7 @@ parallelize_loops (void)
|| loop_has_blocks_with_irreducible_flag (loop)
|| (loop_preheader_edge (loop)->src->flags & BB_IRREDUCIBLE_LOOP)
/* FIXME: the check for vector phi nodes could be removed. */
|| loop_has_vector_phi_nodes (loop)
/* FIXME: transform_to_exit_first_loop does not handle not
header-copied loops correctly - see PR46886. */
|| !do_while_loop_p (loop))
|| loop_has_vector_phi_nodes (loop))
continue;
estimated = estimated_stmt_executions_int (loop);