/* Remove dead PHI nodes from block BB. */
-static void
+static bool
remove_dead_phis (basic_block bb)
{
tree prev, phi;
+ bool something_changed = false;
prev = NULL_TREE;
phi = phi_nodes (bb);
{
tree next = PHI_CHAIN (phi);
+ something_changed = true;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Deleting : ");
phi = PHI_CHAIN (phi);
}
}
+ return something_changed;
}
/* Eliminate unnecessary statements. Any instruction not marked as necessary
contributes nothing to the program, and can be deleted. */
-static void
+static bool
eliminate_unnecessary_stmts (void)
{
+ bool something_changed = false;
basic_block bb;
block_stmt_iterator i;
FOR_EACH_BB (bb)
{
/* Remove dead PHI nodes. */
- remove_dead_phis (bb);
+ something_changed |= remove_dead_phis (bb);
}
FOR_EACH_BB (bb)
/* If `i' is not necessary then remove it. */
if (! NECESSARY (t))
- remove_dead_stmt (&i, bb);
+ {
+ remove_dead_stmt (&i, bb);
+ something_changed = true;
+ }
else
{
tree call = get_call_expr_in (t);
}
}
}
+ return something_changed;
}
as the last tree SSA pass, but keep this in mind when you
start experimenting with pass ordering. */
-static void
+static unsigned int
perform_tree_ssa_dce (bool aggressive)
{
struct edge_list *el = NULL;
+ bool something_changed = 0;
tree_dce_init (aggressive);
propagate_necessity (el);
- eliminate_unnecessary_stmts ();
+ something_changed |= eliminate_unnecessary_stmts ();
+ something_changed |= cfg_altered;
- if (aggressive)
+ if (aggressive && something_changed)
free_dominance_info (CDI_POST_DOMINATORS);
/* If we removed paths in the CFG, then we need to update
tree_dce_done (aggressive);
free_edge_list (el);
+
+ if (something_changed)
+ return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect
+ | TODO_remove_unused_locals);
+ else
+ return 0;
}
/* Pass entry points. */
static unsigned int
tree_ssa_dce (void)
{
- perform_tree_ssa_dce (/*aggressive=*/false);
- return 0;
+ return perform_tree_ssa_dce (/*aggressive=*/false);
}
static unsigned int
tree_ssa_dce_loop (void)
{
- perform_tree_ssa_dce (/*aggressive=*/false);
- free_numbers_of_iterations_estimates ();
- scev_reset ();
- return 0;
+ unsigned int todo;
+ todo = perform_tree_ssa_dce (/*aggressive=*/false);
+ if (todo)
+ {
+ free_numbers_of_iterations_estimates ();
+ scev_reset ();
+ }
+ return todo;
}
static unsigned int
tree_ssa_cd_dce (void)
{
- perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
- return 0;
+ return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
}
static bool
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func
- | TODO_update_ssa
- | TODO_cleanup_cfg
- | TODO_ggc_collect
- | TODO_verify_ssa
- | TODO_remove_unused_locals, /* todo_flags_finish */
+ TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */
0 /* letter */
};
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func
- | TODO_update_ssa
- | TODO_cleanup_cfg
- | TODO_verify_ssa, /* todo_flags_finish */
+ TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */
0 /* letter */
};
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func
- | TODO_update_ssa
- | TODO_cleanup_cfg
- | TODO_ggc_collect
- | TODO_verify_ssa
- | TODO_verify_flow, /* todo_flags_finish */
+ TODO_dump_func | TODO_verify_ssa
+ | TODO_verify_flow, /* todo_flags_finish */
0 /* letter */
};