diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0e94ee68a39..eb945484a55 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2017-06-26 Richard Biener + + 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 * doc/invoke.texi (AArch64 Options, -mtune): Re-add falkor and diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 1b3f2695b39..bcda422d89a 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -1087,7 +1087,7 @@ duplicate_block (basic_block bb, edge e, basic_block after) 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 *new_bbs, 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, basic_block *new_bbs, 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. */ diff --git a/gcc/tree-ssa-phionlycprop.c b/gcc/tree-ssa-phionlycprop.c index aa0f50256cd..9fa427ff2f7 100644 --- a/gcc/tree-ssa-phionlycprop.c +++ b/gcc/tree-ssa-phionlycprop.c @@ -420,10 +420,11 @@ eliminate_degenerate_phis_1 (basic_block bb, bitmap interesting_names, 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); } diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 45b9951bf25..fa8f81e9a1a 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -142,21 +142,24 @@ ssa_redirect_edge (edge e, basic_block dest) 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 ; + /* 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); + 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);