https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64164

--- Comment #13 from Alexandre Oliva <aoliva at gcc dot gnu.org> ---
I looked further into why changing gimple_can_coalesce_p didn't work:
build_ssa_conflict_graph only marks conflicts between SSA names if they share
the same base variable.  This explains why we have a conflict in the conflict
map with -DOPT, in which l_4, values_29 and now_30 all have base variables,
whereas without -DOPT they don't.  So, we can't coalesce them with _10 and _28,
even though 10 and 29 do conflict.

I ran a test in which I allowed values_29 and _28 to coalesce, by hooking into
gimple_can_coalesce_p during an -UOPT out-of-ssa and getting it to return true.
 This yielded the same partition map as the -DOPT case, but an empty conflict
map for the reason above.  The sorted coalesce list was the same, too, so we
coalesced values_29 and _28, as in -DOPT, but then, due to the lack of the
conflict, we also coalesced _10 into the same partition.  This experimental
additional invalid coalescing in turn caused other differences in the generated
RTL.

At this point I'll sum up my findings:

- we fail to coalesce during copyrename because we've ruled out, at that point,
coalescing of anonymous SSA names.  as a consequence, only some coalescing
opportunities are taken, leaving some anonymous names that we try to coalesce
first not coalesced

- as a consequence, we fail to coalesce some SSA names because some of the SSA
variables have become anonymous whereas others aren't

- as a consequence, we emit additional copies in additional BBs, and they
survive all the way to the end of compilation

Although changing copyrename to allow coalescing in these cases fixes the
problem, I suppose it would also be possible to change out-of-ssa to
compensate; we would have to somehow mark conflicts between anonymous and
non-anonymous variables in the conflict graph, though.

Reply via email to