Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation fails with backend ran out of registers #24

Open
rlyerly opened this issue Mar 27, 2018 · 1 comment
Open

Compilation fails with backend ran out of registers #24

rlyerly opened this issue Mar 27, 2018 · 1 comment
Assignees
Labels

Comments

@rlyerly
Copy link
Collaborator

rlyerly commented Mar 27, 2018

For some benchmarks, inserting stackmaps into the code causes the following error message:

fatal error: error in backend: ran out of registers during register allocation
clang-3.7: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 3.7.1 (tags/RELEASE_371/final 320332)
Target: x86_64-unknown-linux-gnu
Thread model: posix
clang-3.7: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-3.7: note: diagnostic msg:


PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-3.7: note: diagnostic msg: /tmp/adapt-89f13a.c
clang-3.7: note: diagnostic msg: /tmp/adapt-89f13a.sh
clang-3.7: note: diagnostic msg:


This is caused by the backend pathologically rematerializing lots of values before a stackmap (in InlineSpiller::reMaterializeAll()). Rematerialized values cannot be spilled (to prevent infinite loops in the register allocator), but these values fill up all available registers, especially on x86. This eventually causes the register allocator to choke in the select or split implementation, e.g., RAGreedy::selectOrSplitImpl().

One solution would be to prevent rematerializing values before stackmaps and instead forcing them to be spilled to the stack. Spilled values will fold into the stackmap, cleanly preventing usage of physical registers (which really aren't using the values but are simply recording their location). However, this causes the creation of a large number of new spill slots which are not currently handled in the StackTransformMetadata pass.

The attached files reproduce this behavior.

adapt.tar.gz

@rlyerly
Copy link
Collaborator Author

rlyerly commented Mar 27, 2018

More background

The rematerializing code is built to cheaply reproduce a small number of values for a single instruction. Since almost all machine instructions only use a handful of values, reproducing this small set of values right before the instruction doesn't normally cause issues. The rematerialization code creates small live ranges containing the remat instruction and its use, and prevents if from being evicted or spilled again.

The stackmap intrinsic violates the assumption of a few small values and can have a large number of live values that are rematerialized just for inclusion in the stackmap. This depletes the pool of available registers, causing this error. Note that this issue isn't encountered for call instructions which take a large number of values -- they are custom lowered so that all argument registers are filled and any remaining arguments are spilled to the stack appropriately.

See [1] for more information.

Quick and dirty workaround

The root cause of this issue is a large number of live values across stackmaps. Optimizations exacerbate this problem (as they often trade time for space or increased code size); in particular, inlining seems to cause this in some instances. Compiling with -fno-inline may work around the issue. If not, turning the optimization level to -O0 may also eliminate the issue.

[1] "LLVM Register Allocation" https://www.slideshare.net/chimerawang/llvm-register-allocation-59885569

@rlyerly rlyerly added the bug label Apr 18, 2018
@rlyerly rlyerly self-assigned this Apr 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant