Commit 4cc31a3c by Richard Biener Committed by Richard Biener

tree-scalar-evolution.h (final_value_replacement_loop): Update prototype.

2018-11-05  Richard Biener  <rguenther@suse.de>

	* tree-scalar-evolution.h (final_value_replacement_loop): Update
	prototype.
	* tree-scalar-evolution.c (final_value_replacement_loop): Return
	whether anything was done.
	(scev_const_prop): Remove constant propagation part, fold
	remains into ...
	* tree-ssa-loop.c (pass_scev_cprop::execute): ... here.
	(pass_data_scev_cprop): TODO_cleanup_cfg is now done
	conditionally.

	* gcc.dg/pr41488.c: Scan ivcanon dump instead of sccp one.
	* gcc.dg/tree-ssa/scev-7.c: Likewise.

From-SVN: r265795
parent 18e0c3d1
2018-11-05 Richard Biener <rguenther@suse.de>
* tree-scalar-evolution.h (final_value_replacement_loop): Update
prototype.
* tree-scalar-evolution.c (final_value_replacement_loop): Return
whether anything was done.
(scev_const_prop): Remove constant propagation part, fold
remains into ...
* tree-ssa-loop.c (pass_scev_cprop::execute): ... here.
(pass_data_scev_cprop): TODO_cleanup_cfg is now done
conditionally.
2018-11-05 Jakub Jelinek <jakub@redhat.com> 2018-11-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/87859 PR tree-optimization/87859
2018-11-05 Richard Biener <rguenther@suse.de>
* gcc.dg/pr41488.c: Scan ivcanon dump instead of sccp one.
* gcc.dg/tree-ssa/scev-7.c: Likewise.
2018-11-05 Jakub Jelinek <jakub@redhat.com> 2018-11-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/87859 PR tree-optimization/87859
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-sccp-scev" } */ /* { dg-options "-O2 -fdump-tree-ivcanon-scev" } */
struct struct_t struct struct_t
{ {
...@@ -14,4 +14,4 @@ void foo (struct struct_t* sp, int start, int end) ...@@ -14,4 +14,4 @@ void foo (struct struct_t* sp, int start, int end)
sp->data[i+start] = 0; sp->data[i+start] = 0;
} }
/* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "sccp" } } */ /* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "ivcanon" } } */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-sccp-scev" } */ /* { dg-options "-O2 -fdump-tree-ivcanon-scev" } */
struct struct_t struct struct_t
{ {
...@@ -14,4 +14,4 @@ void foo (struct struct_t* sp, int start, int end) ...@@ -14,4 +14,4 @@ void foo (struct struct_t* sp, int start, int end)
sp->data[i+start] = 0; sp->data[i+start] = 0;
} }
/* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "sccp" } } */ /* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "ivcanon" } } */
...@@ -3537,20 +3537,20 @@ expression_expensive_p (tree expr) ...@@ -3537,20 +3537,20 @@ expression_expensive_p (tree expr)
} }
} }
/* Do final value replacement for LOOP. */ /* Do final value replacement for LOOP, return true if we did anything. */
void bool
final_value_replacement_loop (struct loop *loop) final_value_replacement_loop (struct loop *loop)
{ {
/* If we do not know exact number of iterations of the loop, we cannot /* If we do not know exact number of iterations of the loop, we cannot
replace the final value. */ replace the final value. */
edge exit = single_exit (loop); edge exit = single_exit (loop);
if (!exit) if (!exit)
return; return false;
tree niter = number_of_latch_executions (loop); tree niter = number_of_latch_executions (loop);
if (niter == chrec_dont_know) if (niter == chrec_dont_know)
return; return false;
/* Ensure that it is possible to insert new statements somewhere. */ /* Ensure that it is possible to insert new statements somewhere. */
if (!single_pred_p (exit->dest)) if (!single_pred_p (exit->dest))
...@@ -3563,6 +3563,7 @@ final_value_replacement_loop (struct loop *loop) ...@@ -3563,6 +3563,7 @@ final_value_replacement_loop (struct loop *loop)
= superloop_at_depth (loop, = superloop_at_depth (loop,
loop_depth (exit->dest->loop_father) + 1); loop_depth (exit->dest->loop_father) + 1);
bool any = false;
gphi_iterator psi; gphi_iterator psi;
for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); ) for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); )
{ {
...@@ -3620,6 +3621,7 @@ final_value_replacement_loop (struct loop *loop) ...@@ -3620,6 +3621,7 @@ final_value_replacement_loop (struct loop *loop)
fprintf (dump_file, " with expr: "); fprintf (dump_file, " with expr: ");
print_generic_expr (dump_file, def); print_generic_expr (dump_file, def);
} }
any = true;
def = unshare_expr (def); def = unshare_expr (def);
remove_phi_node (&psi, false); remove_phi_node (&psi, false);
...@@ -3662,100 +3664,8 @@ final_value_replacement_loop (struct loop *loop) ...@@ -3662,100 +3664,8 @@ final_value_replacement_loop (struct loop *loop)
fprintf (dump_file, "\n"); 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);
fprintf (dump_file, " with: ");
print_generic_expr (dump_file, ev);
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; return any;
} }
#include "gt-tree-scalar-evolution.h" #include "gt-tree-scalar-evolution.h"
...@@ -33,7 +33,7 @@ extern tree analyze_scalar_evolution (struct loop *, tree); ...@@ -33,7 +33,7 @@ extern tree analyze_scalar_evolution (struct loop *, tree);
extern tree instantiate_scev (edge, struct loop *, tree); extern tree instantiate_scev (edge, struct loop *, tree);
extern tree resolve_mixers (struct loop *, tree, bool *); extern tree resolve_mixers (struct loop *, tree, bool *);
extern void gather_stats_on_scev_database (void); extern void gather_stats_on_scev_database (void);
extern void final_value_replacement_loop (struct loop *); extern bool final_value_replacement_loop (struct loop *);
extern unsigned int scev_const_prop (void); extern unsigned int scev_const_prop (void);
extern bool expression_expensive_p (tree); extern bool expression_expensive_p (tree);
extern bool simple_iv_with_niters (struct loop *, struct loop *, tree, extern bool simple_iv_with_niters (struct loop *, struct loop *, tree,
......
...@@ -436,8 +436,7 @@ const pass_data pass_data_scev_cprop = ...@@ -436,8 +436,7 @@ const pass_data pass_data_scev_cprop =
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
( TODO_cleanup_cfg 0, /* todo_flags_finish */
| TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
}; };
class pass_scev_cprop : public gimple_opt_pass class pass_scev_cprop : public gimple_opt_pass
...@@ -449,10 +448,24 @@ public: ...@@ -449,10 +448,24 @@ public:
/* opt_pass methods: */ /* opt_pass methods: */
virtual bool gate (function *) { return flag_tree_scev_cprop; } virtual bool gate (function *) { return flag_tree_scev_cprop; }
virtual unsigned int execute (function *) { return scev_const_prop (); } virtual unsigned int execute (function *);
}; // class pass_scev_cprop }; // class pass_scev_cprop
unsigned
pass_scev_cprop::execute (function *)
{
struct loop *loop;
bool any = false;
/* Perform final value replacement in loops, in case the replacement
expressions are cheap. */
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
any |= final_value_replacement_loop (loop);
return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
}
} // anon namespace } // anon namespace
gimple_opt_pass * gimple_opt_pass *
......
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