[LLVM-Backend] [TableGen] [01] : Meaning of various Register classes in Target.td

In the file Target.td at path llvm-project/llvm/include/llvm/Target/Target.td, many related classes are declared, pertaining to Registers. I understand that for implementing a custom backend, one needs to inherit from these classes. I need help understanding what each class means.

Q1: Under the RegInfo class, what is the meaning and use of SpillAlignment, when and how is it used?

Q2: What is the meaning and use of RegisterClass?

Q3: What is the meaning and use of RegisterTuples?

Q4: What is the meaning and use of RegisterCategory?

Q2. A RegisterClass consists of a set of registers and some characteristics that the registers have in common. RegisterClass is needed because you can’t just say “allocate a register on the machine for this operation” - different operations use different sets of registers, for example the integer and floating point registers.

Registers are placed in the set to be considered together. The RegisterClass has one or more types, such as i32 for 32-bit integer. The add operator (among others) in a TD file adds registers to a set in the definition of a RegisterClass. For example RISCV has a RegisterClass called GPR, for general purpose registers. GPR has a type list including i32, and a set of registers built with add. Then instruction selection patterns specify input and output operands as GPR:$rs1 and similar, meaning that the operand must be in a register in GPR. The RegisterClass is also accessible in C++ code, as GPRRegClass in this case. For example RISCVRegisterInfo.cpp uses a method GPRRegClass.contains(DstReg) to determine whether a register belongs to GPR, and createVirtualRegister(&RISCV::GPRRegClass) to create a value that will go in a GPR register.

So a RegisterClass groups registers that are suitable for selecting a particular instruction or allocating a register in a particular case.

“RegisterClass” is not to be confused with the “Register class”. Individual registers are instances of the Register class. Groups of registers are instances of the RegisterClass class. You define registers using Register, and groups of registers using RegisterClass; the definition of a group includes the set of registers in it; the set is often built up with add.

1 Like

Q1 : Under the RegInfo class, what is the meaning and use of SpillAlignment , when and how is it used?

This field is used in RegisterBankInfo.cpp. It isn’t generated by TableGen (yet) and all of the in-tree backends that have GISel implementations set it to 0 in manually constructed PartMappings tables. I’m going to guess and say that it’s maybe used by some out-of-tree backends. According to git blame, it’s Quentin Colombet’s code.

1 Like

The SpillAlignment indicates the minimum required alignment for a stack slot allocated to hold a spilled copy of a register from the associated RegisterClass.

So it is typically used when dealing with spill slots. Search the code base for uses of TargetRegisterInfo::getSpillAlign to see how it is used. I guess the main idea is that to avoid misaligned load/stores when dealing with register spill, it is important to make sure the stack slots allocated for the spilling is fulfilling those minimum alignments.

So the SpillAlignment is definitely used also by in-tree targets. Worth noticing might be that the class in tablegen definitions is called RegInfo, while the tablegen implementation itself (InfoByHwMode.h) is using a struct named RegSizeInfo to track the same info. And then in TargetRegisterInfo this ends up in a struct name RegClassInfo.

1 Like