mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
bf310e122b
commit
69958396d9
|
|
@ -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>
|
2012-04-21 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
PR bootstrap/53021
|
PR bootstrap/53021
|
||||||
|
|
|
||||||
|
|
@ -5595,6 +5595,20 @@ gimple_duplicate_sese_region (edge entry, edge exit,
|
||||||
return true;
|
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
|
/* Duplicates REGION consisting of N_REGION blocks. The new blocks
|
||||||
are stored to REGION_COPY in the same order in that they appear
|
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
|
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_stmt_iterator psi;
|
||||||
gimple phi;
|
gimple phi;
|
||||||
tree def;
|
tree def;
|
||||||
|
struct loop *target, *aloop, *cloop;
|
||||||
|
|
||||||
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
|
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
|
||||||
exits[0] = exit;
|
exits[0] = exit;
|
||||||
|
|
@ -5655,7 +5670,16 @@ gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNU
|
||||||
|
|
||||||
initialize_original_copy_tables ();
|
initialize_original_copy_tables ();
|
||||||
set_loop_copy (orig_loop, loop);
|
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)
|
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));
|
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;
|
PENDING_STMT (e) = NULL;
|
||||||
|
|
||||||
/* Anything that is outside of the region, but was dominated by something
|
/* Anything that is outside of the region, but was dominated by something
|
||||||
|
|
|
||||||
|
|
@ -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 phi, nphi, cond_stmt, stmt, cond_nit;
|
||||||
gimple_stmt_iterator gsi;
|
gimple_stmt_iterator gsi;
|
||||||
tree nit_1;
|
tree nit_1;
|
||||||
edge exit_1;
|
|
||||||
tree new_rhs;
|
|
||||||
|
|
||||||
split_block_after_labels (loop->header);
|
split_block_after_labels (loop->header);
|
||||||
orig_header = single_succ (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);
|
bbs = get_loop_body_in_dom_order (loop);
|
||||||
|
|
||||||
for (n = 0; bbs[n] != loop->latch; n++)
|
for (n = 0; bbs[n] != exit->src; n++)
|
||||||
continue;
|
continue;
|
||||||
nbbs = XNEWVEC (basic_block, n);
|
nbbs = XNEWVEC (basic_block, n);
|
||||||
ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
|
ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
|
||||||
bbs + 1, n, nbbs);
|
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
|
/* Other than reductions, the only gimple reg that should be copied
|
||||||
out of the loop is the control variable. */
|
out of the loop is the control variable. */
|
||||||
|
exit = single_dom_exit (loop);
|
||||||
control_name = NULL_TREE;
|
control_name = NULL_TREE;
|
||||||
for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); )
|
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
|
PHI_RESULT of this phi is the resulting value of the reduction
|
||||||
variable when exiting the loop. */
|
variable when exiting the loop. */
|
||||||
|
|
||||||
exit = single_dom_exit (loop);
|
|
||||||
|
|
||||||
if (htab_elements (reduction_list) > 0)
|
if (htab_elements (reduction_list) > 0)
|
||||||
{
|
{
|
||||||
struct reduction_info *red;
|
struct reduction_info *red;
|
||||||
|
|
@ -2187,10 +2152,7 @@ parallelize_loops (void)
|
||||||
|| loop_has_blocks_with_irreducible_flag (loop)
|
|| loop_has_blocks_with_irreducible_flag (loop)
|
||||||
|| (loop_preheader_edge (loop)->src->flags & BB_IRREDUCIBLE_LOOP)
|
|| (loop_preheader_edge (loop)->src->flags & BB_IRREDUCIBLE_LOOP)
|
||||||
/* FIXME: the check for vector phi nodes could be removed. */
|
/* FIXME: the check for vector phi nodes could be removed. */
|
||||||
|| loop_has_vector_phi_nodes (loop)
|
|| 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))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
estimated = estimated_stmt_executions_int (loop);
|
estimated = estimated_stmt_executions_int (loop);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue