+2017-06-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/80928
+ * cfghooks.c (duplicate_block): Do not copy BB_DUPLICATED flag.
+ (copy_bbs): Set BB_DUPLICATED flag early.
+ (execute_on_growing_pred): Do not execute for BB_DUPLICATED
+ marked blocks.
+ (execute_on_shrinking_pred): Likewise.
+ * tree-ssa.c (ssa_redirect_edge): Do not look for PHI args in
+ BB_DUPLICATED blocks.
+ * tree-ssa-phionlycoprop.c (eliminate_degenerate_phis_1): Properly
+ iterate over all PHIs considering removal of *gsi.
+
2017-06-23 Jim Wilson <jim.wilson@linaro.org>
* doc/invoke.texi (AArch64 Options, -mtune): Re-add falkor and
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
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);
}
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);
}
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++)
{
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. */
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);
}
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);
-
- if (def == NULL_TREE)
- continue;
-
- redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
- }
+ /* 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;
+
+ redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
+ }
e = redirect_edge_succ_nodup (e, dest);