Question about registers and subregisters

Is the relation between registers and their subregisters transitive?
That is, supposing I have registers

  ABCD
  ABC
  AB
  A

such that ABCD has subregister ABC, ABC has subregister AB and AB has
subregister A. Does LLVM recognize that A is also a subregister of ABCD?

Also, suppose now that my registers are

  ABC
  ADE
  AB
  AD
  A

with a relationship similar to the one described above, such that ABC
and ADE are not in any kind of register-subregister relationship but
still partially overlap. Is LLVM able to recognize this, and treat the
situation accordingly (when spilling, etc)?

Thanks,
Francesco

Hi Francesco,

Yes, the subreg are transitive but the transitivity may not be represented the way you expect.

Essentially all the registers map to a set of register units. Two registers overlap if their register units overlap.
The register units are not necessarily actual register.

E.g., in your first example, ABCD maps to the reg unit A, B, C, and D.
In your second example, ADE maps to A and AD maps to A as well. Assuming D and E are not physically accessible by themselves.

You can take query the regunits using the related MCRegisterInfo API, e.g., MCRegUnitIterator.

Hope this helps.

Cheers,
-Quentin

Thanks Quentin, it does help!
I'm referring to the docs at
https://llvm.org/docs/WritingAnLLVMBackend.html#register-set-and-register-classes

How do register units play into the registers/register classes/register
sets described there?

The situation I mentioned in my original mail would be implemented
something like this, if I am not mistaken:

def A : Register<"A">;
def AB : Register<"AB"> {
  let SubRegs = [ A ];
};
def ABC : Register<"ABC"> {
  let SubRegs = [ AB ];
};
def ABCD : Register<"ABCD"> {
  let SubRegs = [ ABC ];
};

Are the underlying register units automagically generated by TableGen?

Best regards,
Francesco

Thanks Quentin, it does help!
I’m referring to the docs at
https://llvm.org/docs/WritingAnLLVMBackend.html#register-set-and-register-classes

How do register units play into the registers/register classes/register
sets described there?

The situation I mentioned in my original mail would be implemented
something like this, if I am not mistaken:

def A : Register<“A”>;
def AB : Register<“AB”> {
let SubRegs = [ A ];
};
def ABC : Register<“ABC”> {
let SubRegs = [ AB ];
};
def ABCD : Register<“ABCD”> {
let SubRegs = [ ABC ];
};

Looks right to me.

Are the underlying register units automagically generated by TableGen?

Yes the register units are automatically generated by TableGen.
You can see this in YourTargetGenRegisterInfo.inc in your build directory.
The MCRegisterDesc describes the register units for each register (5th field) (hard to see though :)).
And the full list of units stored in the variable YourTargetRegUnitRoots.

Honestly, unless your needs are not covered by the existing APIs, I wouldn’t dig into that stuff. The way that stuff is represented is not super important.