This is an archive of the discontinued LLVM Phabricator instance.

[RegAlloc] Fix "ran out of regs" with uses in statepoint
ClosedPublic

Authored by skatkov on Mar 17 2021, 2:21 AM.

Details

Summary

Statepoint instruction is known to have a variable and big number of operands.
It is possible that Register Allocator will split live intervals in the way that all
physical registers are occupied by "zero-length" live intervals which are marked
as not-spillable.
While intervals are marked as not-spillable in the moment of creation when they are
really zero-length it is possible that in future as part of re-materialization there will
need for physical register between def and use of such tiny interval (the use is not
related to this interval at all).
As all physical registers are assigned to not-spillable intervals there is not avaialbe
registers and RA reports an error.

The idea of the fix is avoid marking tiny live intervals where there is a use in statepoint
instruction in var args section. Such interval may be perfectly spilled and folded to
operand of statepoint.

Diff Detail

Event Timeline

skatkov created this revision.Mar 17 2021, 2:21 AM
skatkov requested review of this revision.Mar 17 2021, 2:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 17 2021, 2:21 AM
skatkov edited reviewers, added: dmgreen; removed: greened.Mar 17 2021, 2:23 AM
skatkov edited the summary of this revision. (Show Details)

LGTM w/comments address. Please hold submit for a couple of days for other reviewers to comment if desired.

For those reading along, Serguei and I have talked about alternatives extensively in offline discussion. I really wanted a patch which could be generic (i.e. not specific to statepoints here), but every variant we tried hit either crashes or infinite loops in the register allocator. The "basic" register allocator in particular is extraordinarily sensitive to this piece of code and relies on short live ranges being marked not spillable for forward progress. I view this patch as a workaround rather than a true fix, but I can't continue to block a workaround without an idea of how to fix something the "right way".

The risk with this patch is that the register allocator may fail to make progress on the short live range intervals. When exploring offline (with a variant, of a variant, of a variant of this patch), I saw at least one case where allowing the registers created by spiltting to be assigned normally seemed to cause an infinite split loop. I'd traced that one far enough to be reasonably convinced it was simply a latent bug in last chance recoloring, but am not sure of my diagnosis.

llvm/include/llvm/CodeGen/CalcSpillWeights.h
53

This comment tries to explain too much and is simply confusing. I'd describe what this function does here, and then the purpose at the call site.

reames accepted this revision.Mar 17 2021, 5:30 PM
This revision is now accepted and ready to land.Mar 17 2021, 5:30 PM
This revision was landed with ongoing or failed builds.Mar 23 2021, 9:01 PM
This revision was automatically updated to reflect the committed changes.