Tying an instruction to a specific set of registers

Is there a way in tablegen to specify that a certain instruction can only be allocated with a certain subset of a register class?

Thanks,
Micah

Hi Micah,

You can just create a new register class that only contains the registers you want and use that for the instruction. The set theoretic operators for register class definition make this very easy. See the ARM backend definitions of GPRnopc, rGPR, etc.. for examples.

-Jim

Jim,
Thanks for the hints. Does LLVM allow allocation of the same register across register classes?

For example, in the ARM backend, can an instruction write to R0 when it is part of register class tGPR, but then use R0 in the next instruction as a source register from the rGPR class?

If LLVM can do this, then this will work.

Micah

Jim,
Thanks for the hints. Does LLVM allow allocation of the same register across register classes?

Yes.

For example, in the ARM backend, can an instruction write to R0 when it is part of register class tGPR, but then use R0 in the next instruction as a source register from the rGPR class?

If LLVM can do this, then this will work.

This should all work.

It is a good idea to ensure that for all overlapping register classes, the intersection is also a register class. Then the coalescer will use that class when joining cross-class copies.

I am planning to teach tablegen to infer these register classes automatically, but for now you need to create them manually.

/jakob

Hi Micah,

Yes, the allocator handles that just fine. The ARM backend relies very heavily on that, actually, so it's a well tested area of the allocator.

If you introspect the code along the way, you'll likely see a fair number of COPY instructions as a result, but those get coalesced away for cases like these, so you won't need to do anything special for them.

As a side note, you may also want to look at the storeRegFromStackSlot() and loadRegFromStackSlot() functions for how they handle the register classes. Specifically, the use of hasSubClassEq() rather than an explicit == for checking which class is being dealt with.

-Jim