lra-lives.c
46.4 KB
-
lra: Stop registers being incorrectly marked live [PR92989] · e648e57e
lra_assign has an assert to make sure that no pseudo is allocated to a conflicting hard register. It used to be restricted to !flag_ipa_ra, but in g:a1e6ee38 I'd enabled it for flag_ipa_ra too. It then tripped while building libstdc++ for mips-mti-linux. The failure was due to code at the end of process_bb_lives. For an abnormal/EH edge, we need to make sure that all pseudos that are live on entry to the destination conflict with all hard registers that are clobbered by an abnormal call return. The usual way to do this would be to simulate a clobber of the hard registers, by making them live and them making them dead again. Making the registers live creates the conflict; making them dead again restores the correct live set for whatever follows. However, process_bb_lives skips the second step (making the registers dead again) at the start of a BB, presumably on the basis that there's no further code that needs a correct live set. The problem for the PR is that that wasn't quite true in practice. There was code further down process_bb_lives that updated the live-in set of the BB for some registers, and this live set was "contaminated" by registers that weren't live but that created conflicts. This information then got propagated to other blocks, so that registers that were made live purely to create a conflict at the start of the EH receiver then became needlessly live throughout preceding blocks. This in turn created a fake conflict with pseudos in those blocks, invalidating the choices made by IRA. The easiest fix seems to be to update the live-in set *before* adding the fake live registers. An alternative would be to simulate the full clobber, but that seems a bit wasteful. 2020-01-27 Richard Sandiford <richard.sandiford@arm.com> gcc/ PR rtl-optimization/92989 * lra-lives.c (process_bb_lives): Update the live-in set before processing additional clobbers.
Richard Sandiford committed