Commit 684aaf29 by Zdenek Dvorak Committed by Zdenek Dvorak

timevar.def (TV_SCEV_CONST): New timevar.

	* timevar.def (TV_SCEV_CONST): New timevar.
	* tree-optimize.c (init_tree_optimization_passes): Add
	pass_scev_cprop.
	* tree-pass.h (pass_scev_cprop): Declare.
	* tree-scalar-evolution.c (scev_const_prop): New function.
	* tree-scalar-evolution.h (scev_const_prop): Declare.
	* tree-ssa-loop.c (gate_scev_const_prop, pass_scev_cprop):
	New.
	* tree-cfg.c (replace_uses_by): Export.
	* tree-flow.h (replace_uses_by): Declare.

From-SVN: r99860
parent 7dc5e635
2005-05-17 Zdenek Dvorak <dvorakz@suse.cz>
* timevar.def (TV_SCEV_CONST): New timevar.
* tree-optimize.c (init_tree_optimization_passes): Add
pass_scev_cprop.
* tree-pass.h (pass_scev_cprop): Declare.
* tree-scalar-evolution.c (scev_const_prop): New function.
* tree-scalar-evolution.h (scev_const_prop): Declare.
* tree-ssa-loop.c (gate_scev_const_prop, pass_scev_cprop):
New.
* tree-cfg.c (replace_uses_by): Export.
* tree-flow.h (replace_uses_by): Declare.
2005-05-17 Mike Stump <mrs@apple.com> 2005-05-17 Mike Stump <mrs@apple.com>
Yet more Objective-C++... Yet more Objective-C++...
......
...@@ -95,6 +95,7 @@ DEFTIMEVAR (TV_TREE_LOOP , "tree loop optimization") ...@@ -95,6 +95,7 @@ DEFTIMEVAR (TV_TREE_LOOP , "tree loop optimization")
DEFTIMEVAR (TV_TREE_LOOP_BOUNDS , "tree loop bounds") DEFTIMEVAR (TV_TREE_LOOP_BOUNDS , "tree loop bounds")
DEFTIMEVAR (TV_LIM , "loop invariant motion") DEFTIMEVAR (TV_LIM , "loop invariant motion")
DEFTIMEVAR (TV_TREE_LOOP_IVCANON , "tree canonical iv") DEFTIMEVAR (TV_TREE_LOOP_IVCANON , "tree canonical iv")
DEFTIMEVAR (TV_SCEV_CONST , "scev constant prop")
DEFTIMEVAR (TV_TREE_LOOP_UNSWITCH , "tree loop unswitching") DEFTIMEVAR (TV_TREE_LOOP_UNSWITCH , "tree loop unswitching")
DEFTIMEVAR (TV_COMPLETE_UNROLL , "complete unrolling") DEFTIMEVAR (TV_COMPLETE_UNROLL , "complete unrolling")
DEFTIMEVAR (TV_TREE_VECTORIZATION , "tree vectorization") DEFTIMEVAR (TV_TREE_VECTORIZATION , "tree vectorization")
......
...@@ -1323,7 +1323,7 @@ tree_can_merge_blocks_p (basic_block a, basic_block b) ...@@ -1323,7 +1323,7 @@ tree_can_merge_blocks_p (basic_block a, basic_block b)
/* Replaces all uses of NAME by VAL. */ /* Replaces all uses of NAME by VAL. */
static void void
replace_uses_by (tree name, tree val) replace_uses_by (tree name, tree val)
{ {
imm_use_iterator imm_iter; imm_use_iterator imm_iter;
......
...@@ -543,6 +543,7 @@ extern tree gimplify_build3 (block_stmt_iterator *, enum tree_code, ...@@ -543,6 +543,7 @@ extern tree gimplify_build3 (block_stmt_iterator *, enum tree_code,
tree, tree, tree, tree); tree, tree, tree, tree);
extern void init_empty_tree_cfg (void); extern void init_empty_tree_cfg (void);
extern void fold_cond_expr_cond (void); extern void fold_cond_expr_cond (void);
extern void replace_uses_by (tree, tree);
/* In tree-pretty-print.c. */ /* In tree-pretty-print.c. */
extern void dump_generic_bb (FILE *, basic_block, int, int); extern void dump_generic_bb (FILE *, basic_block, int, int);
......
...@@ -472,6 +472,7 @@ init_tree_optimization_passes (void) ...@@ -472,6 +472,7 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_lim); NEXT_PASS (pass_lim);
NEXT_PASS (pass_unswitch); NEXT_PASS (pass_unswitch);
NEXT_PASS (pass_scev_cprop);
NEXT_PASS (pass_record_bounds); NEXT_PASS (pass_record_bounds);
NEXT_PASS (pass_linear_transform); NEXT_PASS (pass_linear_transform);
NEXT_PASS (pass_iv_canon); NEXT_PASS (pass_iv_canon);
......
...@@ -173,6 +173,7 @@ extern struct tree_opt_pass pass_loop_init; ...@@ -173,6 +173,7 @@ extern struct tree_opt_pass pass_loop_init;
extern struct tree_opt_pass pass_lim; extern struct tree_opt_pass pass_lim;
extern struct tree_opt_pass pass_unswitch; extern struct tree_opt_pass pass_unswitch;
extern struct tree_opt_pass pass_iv_canon; extern struct tree_opt_pass pass_iv_canon;
extern struct tree_opt_pass pass_scev_cprop;
extern struct tree_opt_pass pass_record_bounds; extern struct tree_opt_pass pass_record_bounds;
extern struct tree_opt_pass pass_if_conversion; extern struct tree_opt_pass pass_if_conversion;
extern struct tree_opt_pass pass_vectorize; extern struct tree_opt_pass pass_vectorize;
......
...@@ -2627,3 +2627,72 @@ scev_finalize (void) ...@@ -2627,3 +2627,72 @@ scev_finalize (void)
BITMAP_FREE (already_instantiated); BITMAP_FREE (already_instantiated);
} }
/* Replace ssa names for that scev can prove they are constant by the
appropriate constants. Most importantly, this takes care of final
value replacement.
We only consider SSA names defined by phi nodes; rest is left to the
ordinary constant propagation pass. */
void
scev_const_prop (void)
{
basic_block bb;
tree name, phi, type, ev;
struct loop *loop;
bitmap ssa_names_to_remove = NULL;
if (!current_loops)
return;
FOR_EACH_BB (bb)
{
loop = bb->loop_father;
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
name = PHI_RESULT (phi);
if (!is_gimple_reg (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));
if (!is_gimple_min_invariant (ev)
|| !may_propagate_copy (name, ev))
continue;
/* Replace the uses of the name. */
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;
unsigned i;
EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
{
name = ssa_name (i);
phi = SSA_NAME_DEF_STMT (name);
gcc_assert (TREE_CODE (phi) == PHI_NODE);
remove_phi_node (phi, NULL);
}
BITMAP_FREE (ssa_names_to_remove);
scev_reset ();
}
}
...@@ -33,5 +33,6 @@ extern tree instantiate_parameters (struct loop *, tree); ...@@ -33,5 +33,6 @@ extern tree instantiate_parameters (struct loop *, tree);
extern void gather_stats_on_scev_database (void); extern void gather_stats_on_scev_database (void);
extern void scev_analysis (void); extern void scev_analysis (void);
extern bool simple_iv (struct loop *, tree, tree, tree *, tree *, bool); extern bool simple_iv (struct loop *, tree, tree, tree *, tree *, bool);
void scev_const_prop (void);
#endif /* GCC_TREE_SCALAR_EVOLUTION_H */ #endif /* GCC_TREE_SCALAR_EVOLUTION_H */
...@@ -286,6 +286,31 @@ struct tree_opt_pass pass_iv_canon = ...@@ -286,6 +286,31 @@ struct tree_opt_pass pass_iv_canon =
0 /* letter */ 0 /* letter */
}; };
/* Propagation of constants using scev. */
static bool
gate_scev_const_prop (void)
{
return true;
}
struct tree_opt_pass pass_scev_cprop =
{
"sccp", /* name */
gate_scev_const_prop, /* gate */
scev_const_prop, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_SCEV_CONST, /* tv_id */
PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func, /* todo_flags_finish */
0 /* letter */
};
/* Record bounds on numbers of iterations of loops. */ /* Record bounds on numbers of iterations of loops. */
static void static void
......
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