This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Making VRegs w/ LLTs and RegClasses both illegal
Needs ReviewPublic

Authored by rtereshin on Apr 17 2018, 11:49 AM.

Details

Summary

anywhere but mid-InstructionSelect pass.

The rationale behind this is the consideration that dealing w/
instructions that def/use VRegs each of which could be in one of the 3
configurations:

a) LLT (optional RegBank)
b) RegClass
c) LLT and RegClass both

throughout the GlobalISel is getting tedious and error-prone very
quickly as the number of VRegs def/used increases, and it's better to
forbid the config (c) altogether to simplify the implementation and
decrease the number of hidden bugs. Apparently, the GlobalISel
implementation already assumes that in a few places, this decision was
made a while ago, but it was never actually enforced.

This commit explicitly enforces the invariant at passes' boundaries
with MachineVerifier, and implicitly intra-pass except
InstructionSelect, which is expected to introduce such VRegs for
performance reasons, as the pass eliminates LLTs by the end of it
anyway.

This patch also tries its best to fix all the failures that came out
of it. The most affected parts are:

  1. CallLowering: lowering ABI naturally introduces a few selected MIR / non-selected MIR boundaries, which many targets shaped with LLT + RegClass VRegs, now illegal.
  1. selectCopy: as GlobalISel doesn't supply tools for assigning RegClasses during selection to def/uses of COPYs, this is done by every target independently in a very similar manner with common drawbacks, e.g. assuming that SRC-vreg of a COPY could not have (meaningful) RegClass attached and whatnot. As the number of COPYs between typed and regclassed VRegs increases with this commit, some of these issues got exposed and had to be fixed to the best of my understanding of the target-specific implementation.
  1. constrainOperandRegClass set of GlobalISel utils, apparently promising but not delivering auto-COPY-insertion for defs, not just uses was fixed as well and updated in a way that should make it easier to migrate legalizer-implementations and other parts of non-upstream targets.

This is related to, but not dependent on https://reviews.llvm.org/D45644 and https://reviews.llvm.org/D45640

Diff Detail

Repository
rL LLVM

Event Timeline

rtereshin created this revision.Apr 17 2018, 11:49 AM
rtereshin updated this revision to Diff 143669.Apr 23 2018, 3:52 PM

Rebased against thunk and removed a test that is no longer valid due to https://reviews.llvm.org/rL330660 (https://reviews.llvm.org/D45644)

Also, I wonder if there would be passes (non ISEL), that would break the invariant intra pass, but cleans up at the end of the pass..

lib/CodeGen/GlobalISel/IRTranslator.cpp
596

This can be simplified into a more compact form (if you care enough).

auto MIB = MIRBuilder.buildCopy(DstReg,
                          MIRBuilder.buildInstr(TRI->getPointerRegClass(*MF), LOAD_STACK_GUARD))

Also, I wonder if there would be passes (non ISEL), that would break the invariant intra pass, but cleans up at the end of the pass..

I don't know, maybe? It's probably not going too much against this patch, I just decided to maintain invariant intra pass to make this work for existing passes. New passes are free to make a different decision and clean up at the end of the pass, they will have the opportunity to call the constrain reg classes helper functions and methods with ISel = true to stop them from maintaining the invariant. If that happens, we will rename the function argument so it doesn't suggest instruction select pass specifically anymore.

Sounds good?

Also, thanks for looking into this.

rtereshin updated this revision to Diff 145785.May 8 2018, 2:23 PM
rtereshin marked an inline comment as done.

Rebasing against master (there was a patch committed containing some of the changes from this one), addressing comments, and tidying up the patch a little.