===================================================================
@@ -1087,7 +1087,7 @@ duplicate_block (basic_block bb, edge e,
if (after)
move_block_after (new_bb, after);
- new_bb->flags = bb->flags;
+ new_bb->flags = (bb->flags & ~BB_DUPLICATED);
FOR_EACH_EDGE (s, ei, bb->succs)
{
/* Since we are creating edges from a new block to successors
@@ -1207,7 +1207,8 @@ flow_call_edges_add (sbitmap blocks)
void
execute_on_growing_pred (edge e)
{
- if (cfg_hooks->execute_on_growing_pred)
+ if (! (e->dest->flags & BB_DUPLICATED)
+ && cfg_hooks->execute_on_growing_pred)
cfg_hooks->execute_on_growing_pred (e);
}
@@ -1217,7 +1218,8 @@ execute_on_growing_pred (edge e)
void
execute_on_shrinking_pred (edge e)
{
- if (cfg_hooks->execute_on_shrinking_pred)
+ if (! (e->dest->flags & BB_DUPLICATED)
+ && cfg_hooks->execute_on_shrinking_pred)
cfg_hooks->execute_on_shrinking_pred (e);
}
@@ -1353,6 +1355,12 @@ copy_bbs (basic_block *bbs, unsigned n,
basic_block bb, new_bb, dom_bb;
edge e;
+ /* Mark the blocks to be copied. This is used by edge creation hooks
+ to decide whether to reallocate PHI nodes capacity to avoid reallocating
+ PHIs in the set of source BBs. */
+ for (i = 0; i < n; i++)
+ bbs[i]->flags |= BB_DUPLICATED;
+
/* Duplicate bbs, update dominators, assign bbs to loops. */
for (i = 0; i < n; i++)
{
@@ -1360,7 +1368,6 @@ copy_bbs (basic_block *bbs, unsigned n,
bb = bbs[i];
new_bb = new_bbs[i] = duplicate_block (bb, NULL, after);
after = new_bb;
- bb->flags |= BB_DUPLICATED;
if (bb->loop_father)
{
/* Possibly set loop header. */
===================================================================
@@ -420,10 +420,11 @@ eliminate_degenerate_phis_1 (basic_block
basic_block son;
bool cfg_altered = false;
- for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);)
{
gphi *phi = gsi.phi ();
-
+ /* We might end up removing PHI so advance the iterator now. */
+ gsi_next (&gsi);
cfg_altered |= eliminate_const_or_copy (phi, interesting_names,
need_eh_cleanup);
}
===================================================================
@@ -142,21 +142,24 @@ ssa_redirect_edge (edge e, basic_block d
redirect_edge_var_map_clear (e);
- /* Remove the appropriate PHI arguments in E's destination block. */
- for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- tree def;
- source_location locus ;
-
- phi = gsi.phi ();
- def = gimple_phi_arg_def (phi, e->dest_idx);
- locus = gimple_phi_arg_location (phi, e->dest_idx);
+ /* Remove the appropriate PHI arguments in E's destination block.
+ If we are redirecting a copied edge the destination has not
+ got PHI argument space reserved nor an interesting argument. */
+ if (! (e->dest->flags & BB_DUPLICATED))
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ tree def;
+ source_location locus ;
+
+ phi = gsi.phi ();
+ def = gimple_phi_arg_def (phi, e->dest_idx);
+ locus = gimple_phi_arg_location (phi, e->dest_idx);
- if (def == NULL_TREE)
- continue;
+ if (def == NULL_TREE)
+ continue;
- redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
- }
+ redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
+ }
e = redirect_edge_succ_nodup (e, dest);