On 2021-01-07 6:01 a.m., Richard Sandiford wrote:
Vladimir Makarov via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
The following fixes

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

The patch was successfully bootstrapped on x86-64.
Can you explain this a bit more?  The assert fires if the register
allocation is inconsistent with the conflict information.  What causes
the inconsistency in this case, and why is it OK for the inconsistency
to persist until the next lra_assign pass?  Does something fix up the
inconsistency later, or is the inconsistent information never used?

Sorry, Richard.  I should have described it in more details in the bugzilla.

Hard register splitting was added to remove reload failures to find a hard register after the first scheduling.  Although unfortunately it does not remove all the 1st insn scheduling problems.

A pseudo (p1) lives through insn and one insn alternative requires a specific hard reg (dx in this case) although there is no explicit hard register in the insn (simply another pseudo p2 in the insn requires a class containing only dx reg).  So the pseudo p1 does not have conflict with dx for now and p1 was assigned to dx.

Now constraint sub-pass choose the insn alternative and the next assign sub-pass creates a reload pseudo rp2 for p2 and tries to assign dx to rp2.  It fails and we made hard reg splitting to assign dx to a reload pseudo of rp2.

p3<-dx

insn (rp2)

dx<-p3

After this transformation p1 now got dx as a conflicting reg and allocation is incorrect at this stage as p1 assigned to dx living through the insns conflicts explicitly with dx.

Next assign subpass is trying to assign dx to rp2 by spilling p1 (and assigning another hard reg to p1).

At the end p2,rp2,p3 get dx and all trivial moves (dx <- dx) are removed.

That is explanation when we have an incorrect allocation.

I also should say that LRA has a final register allocation check.  The check in assign sub-pass is for earlier bug recognition during initial LRA development and probably is not necessary anymore.  So another solution would be remove the check in assign sub-pass at all.  But I decided not to do this as it still permits to find some bugs earlier.

Is there no chance of lra_split_hard_reg_for updating the information
itself, to keep everything self-consistent?
I think it would be the old reload approach (ignoring sub-pass separation and making all in on place).  To correct allocations right in lra_split_hard_reg_for we would need to check all pseudos living through the new insns (and for this we need correct live info) and spill pseudos conflicting with split hard reg.  But we don't need to do this as right after splitting sub-pass we have live info sub-pass and assign sub-pass which make all of this.
   Bypassing the check for
every pseudo register seems like quite a big hammer.

I'm not saying this is the wrong fix.  I just think it would help
to have more commentary explaining the situation.


Reply via email to