+/* Forward edge E to respective POST_DOM_BB and update PHIs. */
+
+static edge
+forward_edge_to_pdom (edge e, basic_block post_dom_bb)
+{
+ gimple_stmt_iterator gsi;
+ edge e2 = NULL;
+ edge_iterator ei;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Redirecting edge %i->%i to %i\n", e->src->index,
+ e->dest->index, post_dom_bb->index);
+
+ e2 = redirect_edge_and_branch (e, post_dom_bb);
+ cfg_altered = true;
+
+ /* If edge was already around, no updating is neccesary. */
+ if (e2 != e)
+ return e2;
+
+ if (!gimple_seq_empty_p (phi_nodes (post_dom_bb)))
+ {
+ /* We are sure that for every live PHI we are seeing control dependent BB.
+ This means that we can pick any edge to duplicate PHI args from. */
+ FOR_EACH_EDGE (e2, ei, post_dom_bb->preds)
+ if (e2 != e)
+ break;
+ for (gsi = gsi_start_phis (post_dom_bb); !gsi_end_p (gsi);)
+ {
+ gimple phi = gsi_stmt (gsi);
+ tree op;
+ source_location locus;
+
+ /* PHIs for virtuals have no control dependency relation on them.
+ We are lost here and must force renaming of the symbol. */
+ if (!is_gimple_reg (gimple_phi_result (phi)))
+ {
+ mark_virtual_phi_result_for_renaming (phi);
+ remove_phi_node (&gsi, true);
+ continue;
+ }
+
+ /* Dead PHI do not imply control dependency. */
+ if (!gimple_plf (phi, STMT_NECESSARY))
+ {
+ gsi_next (&gsi);
+ continue;
+ }
+
+ op = gimple_phi_arg_def (phi, e2->dest_idx);
+ locus = gimple_phi_arg_location (phi, e2->dest_idx);
+ add_phi_arg (phi, op, e, locus);
+ /* The resulting PHI if not dead can only be degenerate. */
+ gcc_assert (degenerate_phi_p (phi));
+ gsi_next (&gsi);
+ }
+ }
+ return e;
+}