extern gimple_opt_pass *make_pass_split_crit_edges (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_laddress (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_pre (gcc::context *ctxt);
-extern unsigned int tail_merge_optimize (unsigned int);
+extern unsigned int tail_merge_optimize (unsigned int, bool);
extern gimple_opt_pass *make_pass_profile (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_strip_predict_hints (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_lower_complex_O0 (gcc::context *ctxt);
value_expressions.release ();
constant_value_expressions.release ();
expressions.release ();
- BITMAP_FREE (inserted_exprs);
bitmap_obstack_release (&grand_bitmap_obstack);
bitmap_set_pool.release ();
pre_expr_pool.release ();
vn_valueize = NULL;
+ fini_pre ();
+
+ scev_finalize ();
+ loop_optimizer_finalize ();
+
+ /* Perform a CFG cleanup before we run simple_dce_from_worklist since
+ unreachable code regions will have not up-to-date SSA form which
+ confuses it. */
+ bool need_crit_edge_split = false;
+ if (todo & TODO_cleanup_cfg)
+ {
+ cleanup_tree_cfg ();
+ todo &= ~TODO_cleanup_cfg;
+ need_crit_edge_split = true;
+ }
+
/* Because we don't follow exactly the standard PRE algorithm, and decide not
to insert PHI nodes sometimes, and because value numbering of casts isn't
perfect, we sometimes end up inserting dead code. This simple DCE-like
pass removes any insertions we made that weren't actually used. */
simple_dce_from_worklist (inserted_exprs);
-
- fini_pre ();
-
- scev_finalize ();
- loop_optimizer_finalize ();
+ BITMAP_FREE (inserted_exprs);
/* TODO: tail_merge_optimize may merge all predecessors of a block, in which
case we can merge the block with the remaining predecessor of the block.
- call merge_blocks after all tail merge iterations
- mark TODO_cleanup_cfg when necessary
- share the cfg cleanup with fini_pre. */
- todo |= tail_merge_optimize (todo);
+ todo |= tail_merge_optimize (todo, need_crit_edge_split);
free_rpo_vn ();
/* Runs tail merge optimization. */
unsigned int
-tail_merge_optimize (unsigned int todo)
+tail_merge_optimize (unsigned int todo, bool need_crit_edge_split)
{
int nr_bbs_removed_total = 0;
int nr_bbs_removed;
timevar_push (TV_TREE_TAIL_MERGE);
- /* We enter from PRE which has critical edges split. Elimination
- does not process trivially dead code so cleanup the CFG if we
- are told so. And re-split critical edges then. */
- if (todo & TODO_cleanup_cfg)
- {
- cleanup_tree_cfg ();
- todo &= ~TODO_cleanup_cfg;
- split_edges_for_insertion ();
- }
+ /* Re-split critical edges when PRE did a CFG cleanup. */
+ if (need_crit_edge_split)
+ split_edges_for_insertion ();
if (!dom_info_available_p (CDI_DOMINATORS))
{