Commit f993a853 by Tom de Vries Committed by Tom de Vries

Do final value replacement in try_create_reduction_list

2015-11-20  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/68373
	* tree-scalar-evolution.c (final_value_replacement_loop): Factor out of ...
	(scev_const_prop): ... here.
	* tree-scalar-evolution.h (final_value_replacement_loop): Declare.
	* tree-parloops.c (try_create_reduction_list): Call
	final_value_replacement_loop.

	* gcc.dg/autopar/pr68373.c: New test.

From-SVN: r230650
parent 5b5e7b18
2015-11-20 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/68373
* tree-scalar-evolution.c (final_value_replacement_loop): Factor out of ...
(scev_const_prop): ... here.
* tree-scalar-evolution.h (final_value_replacement_loop): Declare.
* tree-parloops.c (try_create_reduction_list): Call
final_value_replacement_loop.
2015-11-20 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/52272
2015-11-20 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/68373
* gcc.dg/autopar/pr68373.c: New test.
2015-11-20 Jakub Jelinek <jakub@redhat.com>
PR c++/67354
......
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops-details" } */
unsigned int
foo (int *a, unsigned int n)
{
unsigned int i;
for (i = 0; i < n; ++i)
a[i] = 1;
return i;
}
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 1 "parloops" } } */
......@@ -2539,6 +2539,9 @@ try_create_reduction_list (loop_p loop,
gcc_assert (exit);
/* Try to get rid of exit phis. */
final_value_replacement_loop (loop);
gather_scalar_reductions (loop, reduction_list);
......
......@@ -3417,124 +3417,38 @@ expression_expensive_p (tree expr)
}
}
/* Replace ssa names for that scev can prove they are constant by the
appropriate constants. Also perform final value replacement in loops,
in case the replacement expressions are cheap.
We only consider SSA names defined by phi nodes; rest is left to the
ordinary constant propagation pass. */
/* Do final value replacement for LOOP. */
unsigned int
scev_const_prop (void)
void
final_value_replacement_loop (struct loop *loop)
{
basic_block bb;
tree name, type, ev;
gphi *phi;
gassign *ass;
struct loop *loop, *ex_loop;
bitmap ssa_names_to_remove = NULL;
unsigned i;
gphi_iterator psi;
if (number_of_loops (cfun) <= 1)
return 0;
FOR_EACH_BB_FN (bb, cfun)
{
loop = bb->loop_father;
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
{
phi = psi.phi ();
name = PHI_RESULT (phi);
if (virtual_operand_p (name))
continue;
type = TREE_TYPE (name);
if (!POINTER_TYPE_P (type)
&& !INTEGRAL_TYPE_P (type))
continue;
ev = resolve_mixers (loop, analyze_scalar_evolution (loop, name),
NULL);
if (!is_gimple_min_invariant (ev)
|| !may_propagate_copy (name, ev))
continue;
/* Replace the uses of the name. */
if (name != ev)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Replacing uses of: ");
print_generic_expr (dump_file, name, 0);
fprintf (dump_file, " with: ");
print_generic_expr (dump_file, ev, 0);
fprintf (dump_file, "\n");
}
replace_uses_by (name, ev);
}
if (!ssa_names_to_remove)
ssa_names_to_remove = BITMAP_ALLOC (NULL);
bitmap_set_bit (ssa_names_to_remove, SSA_NAME_VERSION (name));
}
}
/* Remove the ssa names that were replaced by constants. We do not
remove them directly in the previous cycle, since this
invalidates scev cache. */
if (ssa_names_to_remove)
{
bitmap_iterator bi;
EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
{
gimple_stmt_iterator psi;
name = ssa_name (i);
phi = as_a <gphi *> (SSA_NAME_DEF_STMT (name));
gcc_assert (gimple_code (phi) == GIMPLE_PHI);
psi = gsi_for_stmt (phi);
remove_phi_node (&psi, true);
}
BITMAP_FREE (ssa_names_to_remove);
scev_reset ();
}
/* Now the regular final value replacement. */
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
{
edge exit;
tree def, rslt, niter;
gimple_stmt_iterator gsi;
/* If we do not know exact number of iterations of the loop, we cannot
replace the final value. */
exit = single_exit (loop);
edge exit = single_exit (loop);
if (!exit)
continue;
return;
niter = number_of_latch_executions (loop);
tree niter = number_of_latch_executions (loop);
if (niter == chrec_dont_know)
continue;
return;
/* Ensure that it is possible to insert new statements somewhere. */
if (!single_pred_p (exit->dest))
split_loop_exit_edge (exit);
gsi = gsi_after_labels (exit->dest);
ex_loop = superloop_at_depth (loop,
/* Set stmt insertion pointer. All stmts are inserted before this point. */
gimple_stmt_iterator gsi = gsi_after_labels (exit->dest);
struct loop *ex_loop
= superloop_at_depth (loop,
loop_depth (exit->dest->loop_father) + 1);
gphi_iterator psi;
for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); )
{
phi = psi.phi ();
rslt = PHI_RESULT (phi);
def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
gphi *phi = psi.phi ();
tree rslt = PHI_RESULT (phi);
tree def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
if (virtual_operand_p (def))
{
gsi_next (&psi);
......@@ -3618,7 +3532,7 @@ scev_const_prop (void)
def = force_gimple_operand_gsi (&gsi, def, false, NULL_TREE,
true, GSI_SAME_STMT);
ass = gimple_build_assign (rslt, def);
gassign *ass = gimple_build_assign (rslt, def);
gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
if (dump_file)
{
......@@ -3626,7 +3540,99 @@ scev_const_prop (void)
fprintf (dump_file, "\n");
}
}
}
/* Replace ssa names for that scev can prove they are constant by the
appropriate constants. Also perform final value replacement in loops,
in case the replacement expressions are cheap.
We only consider SSA names defined by phi nodes; rest is left to the
ordinary constant propagation pass. */
unsigned int
scev_const_prop (void)
{
basic_block bb;
tree name, type, ev;
gphi *phi;
struct loop *loop;
bitmap ssa_names_to_remove = NULL;
unsigned i;
gphi_iterator psi;
if (number_of_loops (cfun) <= 1)
return 0;
FOR_EACH_BB_FN (bb, cfun)
{
loop = bb->loop_father;
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
{
phi = psi.phi ();
name = PHI_RESULT (phi);
if (virtual_operand_p (name))
continue;
type = TREE_TYPE (name);
if (!POINTER_TYPE_P (type)
&& !INTEGRAL_TYPE_P (type))
continue;
ev = resolve_mixers (loop, analyze_scalar_evolution (loop, name),
NULL);
if (!is_gimple_min_invariant (ev)
|| !may_propagate_copy (name, ev))
continue;
/* Replace the uses of the name. */
if (name != ev)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Replacing uses of: ");
print_generic_expr (dump_file, name, 0);
fprintf (dump_file, " with: ");
print_generic_expr (dump_file, ev, 0);
fprintf (dump_file, "\n");
}
replace_uses_by (name, ev);
}
if (!ssa_names_to_remove)
ssa_names_to_remove = BITMAP_ALLOC (NULL);
bitmap_set_bit (ssa_names_to_remove, SSA_NAME_VERSION (name));
}
}
/* Remove the ssa names that were replaced by constants. We do not
remove them directly in the previous cycle, since this
invalidates scev cache. */
if (ssa_names_to_remove)
{
bitmap_iterator bi;
EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
{
gimple_stmt_iterator psi;
name = ssa_name (i);
phi = as_a <gphi *> (SSA_NAME_DEF_STMT (name));
gcc_assert (gimple_code (phi) == GIMPLE_PHI);
psi = gsi_for_stmt (phi);
remove_phi_node (&psi, true);
}
BITMAP_FREE (ssa_names_to_remove);
scev_reset ();
}
/* Now the regular final value replacement. */
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
final_value_replacement_loop (loop);
return 0;
}
......
......@@ -33,6 +33,7 @@ extern tree analyze_scalar_evolution (struct loop *, tree);
extern tree instantiate_scev (basic_block, struct loop *, tree);
extern tree resolve_mixers (struct loop *, tree, bool *);
extern void gather_stats_on_scev_database (void);
extern void final_value_replacement_loop (struct loop *);
extern unsigned int scev_const_prop (void);
extern bool expression_expensive_p (tree);
extern bool simple_iv (struct loop *, struct loop *, tree, struct affine_iv *,
......
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