diff --git a/gcc/regcprop.cc b/gcc/regcprop.cc index 1fdc367..5555c4a 100644 --- a/gcc/regcprop.cc +++ b/gcc/regcprop.cc @@ -1384,6 +1384,7 @@ pass_cprop_hardreg::execute (function *fun) bitmap_clear (visited); auto_vec worklist; + auto_vec third_pass; bool any_debug_changes = false; /* We need accurate notes. Earlier passes such as if-conversion may @@ -1425,7 +1426,27 @@ pass_cprop_hardreg::execute (function *fun) for (int index : worklist) { bb = BASIC_BLOCK_FOR_FN (fun, index); - cprop_hardreg_bb (bb, all_vd, visited); + /* Perform a third pass, if the second pass changed anything. + Three passes are required for swaps: t = x; x = y; y = t. */ + if (cprop_hardreg_bb (bb, all_vd, visited)) + third_pass.safe_push (bb->index); + if (all_vd[bb->index].n_debug_insn_changes) + any_debug_changes = true; + } + + df_analyze (); + if (MAY_HAVE_DEBUG_BIND_INSNS && any_debug_changes) + cprop_hardreg_debug (fun, all_vd); + } + + if (!third_pass.is_empty ()) + { + any_debug_changes = false; + bitmap_clear (visited); + for (int index : third_pass) + { + bb = BASIC_BLOCK_FOR_FN (fun, index); + cprop_hardreg_bb (bb, all_vd, visited); if (all_vd[bb->index].n_debug_insn_changes) any_debug_changes = true; }