Commit e67d7a1e by Tom de Vries Committed by Tom de Vries

Don't cancel loop tree in parloops

2015-07-31  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/66846
	* omp-low.c (expand_omp_taskreg) [ENABLE_CHECKING]: Call
	verify_loop_structure for child_cfun if !LOOPS_NEED_FIXUP.
	(expand_omp_target) [ENABLE_CHECKING]: Same.
	(execute_expand_omp) [ENABLE_CHECKING]: Call verify_loop_structure for
	cfun if !LOOPS_NEED_FIXUP.
	(expand_omp_for_static_nochunk): Handle simple latch bb.  Handle case
	that omp_for already has its own loop struct.
	* tree-parloops.c (create_phi_for_local_result)
	(create_call_for_reduction): Handle simple latch bb.
	(create_parallel_loop): Add simple latch bb to preserve
	LOOPS_HAVE_SIMPLE_LATCHES.  Record new exit.  Handle simple latch bb.
	(gen_parallel_loop): Remove call to cancel_loop_tree.
	(parallelize_loops): Skip loops that are inner loops of parallelized
	loops.
	(pass_parallelize_loops::execute) [ENABLE_CHECKING]: Call
	verify_loop_structure.

From-SVN: r226427
parent 048e62c3
2015-07-31 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/66846
* omp-low.c (expand_omp_taskreg) [ENABLE_CHECKING]: Call
verify_loop_structure for child_cfun if !LOOPS_NEED_FIXUP.
(expand_omp_target) [ENABLE_CHECKING]: Same.
(execute_expand_omp) [ENABLE_CHECKING]: Call verify_loop_structure for
cfun if !LOOPS_NEED_FIXUP.
(expand_omp_for_static_nochunk): Handle simple latch bb. Handle case
that omp_for already has its own loop struct.
* tree-parloops.c (create_phi_for_local_result)
(create_call_for_reduction): Handle simple latch bb.
(create_parallel_loop): Add simple latch bb to preserve
LOOPS_HAVE_SIMPLE_LATCHES. Record new exit. Handle simple latch bb.
(gen_parallel_loop): Remove call to cancel_loop_tree.
(parallelize_loops): Skip loops that are inner loops of parallelized
loops.
(pass_parallelize_loops::execute) [ENABLE_CHECKING]: Call
verify_loop_structure.
2015-07-30 Anatoly Sokolov <aesok@post.ru> 2015-07-30 Anatoly Sokolov <aesok@post.ru>
* config/v850/v850.h (LIBCALL_VALUE): Remove macros. * config/v850/v850.h (LIBCALL_VALUE): Remove macros.
......
...@@ -5604,6 +5604,10 @@ expand_omp_taskreg (struct omp_region *region) ...@@ -5604,6 +5604,10 @@ expand_omp_taskreg (struct omp_region *region)
} }
if (gimple_in_ssa_p (cfun)) if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa); update_ssa (TODO_update_ssa);
#ifdef ENABLE_CHECKING
if (!loops_state_satisfies_p (LOOPS_NEED_FIXUP))
verify_loop_structure ();
#endif
pop_cfun (); pop_cfun ();
} }
...@@ -6535,7 +6539,8 @@ expand_omp_for_static_nochunk (struct omp_region *region, ...@@ -6535,7 +6539,8 @@ expand_omp_for_static_nochunk (struct omp_region *region,
body_bb = single_succ (seq_start_bb); body_bb = single_succ (seq_start_bb);
if (!broken_loop) if (!broken_loop)
{ {
gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb); gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb
|| single_succ (BRANCH_EDGE (cont_bb)->dest) == body_bb);
gcc_assert (EDGE_COUNT (cont_bb->succs) == 2); gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
} }
exit_bb = region->exit; exit_bb = region->exit;
...@@ -6818,6 +6823,11 @@ expand_omp_for_static_nochunk (struct omp_region *region, ...@@ -6818,6 +6823,11 @@ expand_omp_for_static_nochunk (struct omp_region *region,
if (!broken_loop) if (!broken_loop)
{ {
ep = find_edge (cont_bb, body_bb); ep = find_edge (cont_bb, body_bb);
if (ep == NULL)
{
ep = BRANCH_EDGE (cont_bb);
gcc_assert (single_succ (ep->dest) == body_bb);
}
if (gimple_omp_for_combined_p (fd->for_stmt)) if (gimple_omp_for_combined_p (fd->for_stmt))
{ {
remove_edge (ep); remove_edge (ep);
...@@ -6843,9 +6853,19 @@ expand_omp_for_static_nochunk (struct omp_region *region, ...@@ -6843,9 +6853,19 @@ expand_omp_for_static_nochunk (struct omp_region *region,
set_immediate_dominator (CDI_DOMINATORS, fin_bb, set_immediate_dominator (CDI_DOMINATORS, fin_bb,
recompute_dominator (CDI_DOMINATORS, fin_bb)); recompute_dominator (CDI_DOMINATORS, fin_bb));
struct loop *loop = body_bb->loop_father;
if (loop != entry_bb->loop_father)
{
gcc_assert (loop->header == body_bb);
gcc_assert (broken_loop
|| loop->latch == region->cont
|| single_pred (loop->latch) == region->cont);
return;
}
if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt)) if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
{ {
struct loop *loop = alloc_loop (); loop = alloc_loop ();
loop->header = body_bb; loop->header = body_bb;
if (collapse_bb == NULL) if (collapse_bb == NULL)
loop->latch = cont_bb; loop->latch = cont_bb;
...@@ -8984,6 +9004,10 @@ expand_omp_target (struct omp_region *region) ...@@ -8984,6 +9004,10 @@ expand_omp_target (struct omp_region *region)
if (changed) if (changed)
cleanup_tree_cfg (); cleanup_tree_cfg ();
} }
#ifdef ENABLE_CHECKING
if (!loops_state_satisfies_p (LOOPS_NEED_FIXUP))
verify_loop_structure ();
#endif
pop_cfun (); pop_cfun ();
} }
...@@ -9492,6 +9516,10 @@ execute_expand_omp (void) ...@@ -9492,6 +9516,10 @@ execute_expand_omp (void)
expand_omp (root_omp_region); expand_omp (root_omp_region);
#ifdef ENABLE_CHECKING
if (!loops_state_satisfies_p (LOOPS_NEED_FIXUP))
verify_loop_structure ();
#endif
cleanup_tree_cfg (); cleanup_tree_cfg ();
free_omp_regions (); free_omp_regions ();
......
...@@ -1032,21 +1032,22 @@ create_phi_for_local_result (reduction_info **slot, struct loop *loop) ...@@ -1032,21 +1032,22 @@ create_phi_for_local_result (reduction_info **slot, struct loop *loop)
struct reduction_info *const reduc = *slot; struct reduction_info *const reduc = *slot;
edge e; edge e;
gphi *new_phi; gphi *new_phi;
basic_block store_bb; basic_block store_bb, continue_bb;
tree local_res; tree local_res;
source_location locus; source_location locus;
/* STORE_BB is the block where the phi /* STORE_BB is the block where the phi
should be stored. It is the destination of the loop exit. should be stored. It is the destination of the loop exit.
(Find the fallthru edge from GIMPLE_OMP_CONTINUE). */ (Find the fallthru edge from GIMPLE_OMP_CONTINUE). */
store_bb = FALLTHRU_EDGE (loop->latch)->dest; continue_bb = single_pred (loop->latch);
store_bb = FALLTHRU_EDGE (continue_bb)->dest;
/* STORE_BB has two predecessors. One coming from the loop /* STORE_BB has two predecessors. One coming from the loop
(the reduction's result is computed at the loop), (the reduction's result is computed at the loop),
and another coming from a block preceding the loop, and another coming from a block preceding the loop,
when no iterations when no iterations
are executed (the initial value should be taken). */ are executed (the initial value should be taken). */
if (EDGE_PRED (store_bb, 0) == FALLTHRU_EDGE (loop->latch)) if (EDGE_PRED (store_bb, 0) == FALLTHRU_EDGE (continue_bb))
e = EDGE_PRED (store_bb, 1); e = EDGE_PRED (store_bb, 1);
else else
e = EDGE_PRED (store_bb, 0); e = EDGE_PRED (store_bb, 0);
...@@ -1055,7 +1056,7 @@ create_phi_for_local_result (reduction_info **slot, struct loop *loop) ...@@ -1055,7 +1056,7 @@ create_phi_for_local_result (reduction_info **slot, struct loop *loop)
locus = gimple_location (reduc->reduc_stmt); locus = gimple_location (reduc->reduc_stmt);
new_phi = create_phi_node (local_res, store_bb); new_phi = create_phi_node (local_res, store_bb);
add_phi_arg (new_phi, reduc->init, e, locus); add_phi_arg (new_phi, reduc->init, e, locus);
add_phi_arg (new_phi, lhs, FALLTHRU_EDGE (loop->latch), locus); add_phi_arg (new_phi, lhs, FALLTHRU_EDGE (continue_bb), locus);
reduc->new_phi = new_phi; reduc->new_phi = new_phi;
return 1; return 1;
...@@ -1134,7 +1135,8 @@ create_call_for_reduction (struct loop *loop, ...@@ -1134,7 +1135,8 @@ create_call_for_reduction (struct loop *loop,
{ {
reduction_list->traverse <struct loop *, create_phi_for_local_result> (loop); reduction_list->traverse <struct loop *, create_phi_for_local_result> (loop);
/* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */ /* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
ld_st_data->load_bb = FALLTHRU_EDGE (loop->latch)->dest; basic_block continue_bb = single_pred (loop->latch);
ld_st_data->load_bb = FALLTHRU_EDGE (continue_bb)->dest;
reduction_list reduction_list
->traverse <struct clsn_data *, create_call_for_reduction_1> (ld_st_data); ->traverse <struct clsn_data *, create_call_for_reduction_1> (ld_st_data);
} }
...@@ -1981,7 +1983,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, ...@@ -1981,7 +1983,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
tree new_data, unsigned n_threads, location_t loc) tree new_data, unsigned n_threads, location_t loc)
{ {
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
basic_block bb, paral_bb, for_bb, ex_bb; basic_block bb, paral_bb, for_bb, ex_bb, continue_bb;
tree t, param; tree t, param;
gomp_parallel *omp_par_stmt; gomp_parallel *omp_par_stmt;
gimple omp_return_stmt1, omp_return_stmt2; gimple omp_return_stmt1, omp_return_stmt2;
...@@ -2052,8 +2054,12 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, ...@@ -2052,8 +2054,12 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
gcc_assert (exit == single_dom_exit (loop)); gcc_assert (exit == single_dom_exit (loop));
guard = make_edge (for_bb, ex_bb, 0); guard = make_edge (for_bb, ex_bb, 0);
single_succ_edge (loop->latch)->flags = 0; /* Split the latch edge, so LOOPS_HAVE_SIMPLE_LATCHES is still valid. */
end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU); loop->latch = split_edge (single_succ_edge (loop->latch));
single_pred_edge (loop->latch)->flags = 0;
end = make_edge (single_pred (loop->latch), ex_bb, EDGE_FALLTHRU);
rescan_loop_exit (end, true, false);
for (gphi_iterator gpi = gsi_start_phis (ex_bb); for (gphi_iterator gpi = gsi_start_phis (ex_bb);
!gsi_end_p (gpi); gsi_next (&gpi)) !gsi_end_p (gpi); gsi_next (&gpi))
{ {
...@@ -2102,7 +2108,8 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, ...@@ -2102,7 +2108,8 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
SSA_NAME_DEF_STMT (initvar) = for_stmt; SSA_NAME_DEF_STMT (initvar) = for_stmt;
/* Emit GIMPLE_OMP_CONTINUE. */ /* Emit GIMPLE_OMP_CONTINUE. */
gsi = gsi_last_bb (loop->latch); continue_bb = single_pred (loop->latch);
gsi = gsi_last_bb (continue_bb);
omp_cont_stmt = gimple_build_omp_continue (cvar_next, cvar); omp_cont_stmt = gimple_build_omp_continue (cvar_next, cvar);
gimple_set_location (omp_cont_stmt, loc); gimple_set_location (omp_cont_stmt, loc);
gsi_insert_after (&gsi, omp_cont_stmt, GSI_NEW_STMT); gsi_insert_after (&gsi, omp_cont_stmt, GSI_NEW_STMT);
...@@ -2298,10 +2305,6 @@ gen_parallel_loop (struct loop *loop, ...@@ -2298,10 +2305,6 @@ gen_parallel_loop (struct loop *loop,
scev_reset (); scev_reset ();
/* Cancel the loop (it is simpler to do it here rather than to teach the
expander to do it). */
cancel_loop_tree (loop);
/* Free loop bound estimations that could contain references to /* Free loop bound estimations that could contain references to
removed statements. */ removed statements. */
FOR_EACH_LOOP (loop, 0) FOR_EACH_LOOP (loop, 0)
...@@ -2587,6 +2590,7 @@ parallelize_loops (void) ...@@ -2587,6 +2590,7 @@ parallelize_loops (void)
unsigned n_threads = flag_tree_parallelize_loops; unsigned n_threads = flag_tree_parallelize_loops;
bool changed = false; bool changed = false;
struct loop *loop; struct loop *loop;
struct loop *skip_loop = NULL;
struct tree_niter_desc niter_desc; struct tree_niter_desc niter_desc;
struct obstack parloop_obstack; struct obstack parloop_obstack;
HOST_WIDE_INT estimated; HOST_WIDE_INT estimated;
...@@ -2604,6 +2608,19 @@ parallelize_loops (void) ...@@ -2604,6 +2608,19 @@ parallelize_loops (void)
FOR_EACH_LOOP (loop, 0) FOR_EACH_LOOP (loop, 0)
{ {
if (loop == skip_loop)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
"Skipping loop %d as inner loop of parallelized loop\n",
loop->num);
skip_loop = loop->inner;
continue;
}
else
skip_loop = NULL;
reduction_list.empty (); reduction_list.empty ();
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
...@@ -2663,6 +2680,7 @@ parallelize_loops (void) ...@@ -2663,6 +2680,7 @@ parallelize_loops (void)
continue; continue;
changed = true; changed = true;
skip_loop = loop->inner;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
if (loop->inner) if (loop->inner)
...@@ -2729,6 +2747,11 @@ pass_parallelize_loops::execute (function *fun) ...@@ -2729,6 +2747,11 @@ pass_parallelize_loops::execute (function *fun)
if (parallelize_loops ()) if (parallelize_loops ())
{ {
fun->curr_properties &= ~(PROP_gimple_eomp); fun->curr_properties &= ~(PROP_gimple_eomp);
#ifdef ENABLE_CHECKING
verify_loop_structure ();
#endif
return TODO_update_ssa; return TODO_update_ssa;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment