Tzu-Chien Chiu
2005-Jul-22 02:29 UTC
[LLVMdev] How to partition registers into different RegisterClass?
Hi, everyone. I' have three set of registers - read-only regs, general purpose regs (read and write), and write-only regs. How should I partition them into different RegisterClasses so that I can easy define the instruction? All RegisterClasses must be mutally exclusive. That is, a register can only be in a RegisterClass. Otherwise TableGen will raise an error message. def ReadOnlyRegClass : RegisterClass<...>; def GeneralPurposeRegClass : RegisterClass<...>; def WriteOnlyRegClass : RegisterClass<...>; def MOV : BinaryInst<2, (ops GeneralPurposeRegClass :$dest, GeneralPurposeRegClass :$src), "mov $dest, $src">; There can be only one RegisterClass defined for each instruction operand, but actually the destition operand could be 'GeneralPurposeRegClass ' or 'WriteOnlyRegClass ', and the source operand can be 'ReadOnlyRegClass' or 'GeneralPurposeRegClass'. -- Tzu-Chien Chiu http://www.csie.nctu.edu.tw/~jwchiu/
Misha Brukman
2005-Jul-22 04:29 UTC
[LLVMdev] How to partition registers into different RegisterClass?
On Fri, Jul 22, 2005 at 10:29:38AM +0800, Tzu-Chien Chiu wrote:> I' have three set of registers - read-only regs, general purpose regs > (read and write), and write-only regs. How should I partition them > into different RegisterClasses so that I can easy define the > instruction?[snip]> def MOV : BinaryInst<2, (ops GeneralPurposeRegClass :$dest, > GeneralPurposeRegClass :$src), "mov $dest, $src">; > > There can be only one RegisterClass defined for each instruction > operand, but actually the destition operand could be > 'GeneralPurposeRegClass ' or 'WriteOnlyRegClass ', and the source > operand can be 'ReadOnlyRegClass' or 'GeneralPurposeRegClass'.Presumably, when you write your instruction selector, you know when you want to have a write-only vs. general purpose and read-only vs. general purpose register. Some things are naturally read-only, such as status registers that are only modified as a side effect of instructions (fp errors, overflow, etc.) and some are write-only registers (I'm guessing video and network cards have these for outputs). So a solution that may work for you would be to define permutations of the instructions that explicitly specify what type of operands your instruction takes (because different instructions need different LLVM opcodes) but the instructions would print out the same, so in your example: MOVgg : General, General MOVwg : Write-only, General MOVwr : Write-only, Read-only Note that if they all have the same "mov $dest, $src" print string, they will be printed out identically, but you need to separate them anyway. If you look at the X86 backend, you might find many flavors of MOV instructions as well, but for a different reason. The best way is to lazily add permutations that you need as you go along, so you don't have to convert your entire .td file(s) over to a complete set of permutations immediately. Good luck, -- Misha Brukman :: http://misha.brukman.net :: http://llvm.cs.uiuc.edu
Tzu-Chien Chiu
2005-Jul-22 10:08 UTC
[LLVMdev] How to partition registers into different RegisterClass?
All registers in my hardware are 4-element vector registers (128-bit). Some are floating point registers, and the others are integer registers. I typedef two packed classes: [4 x float] and [4 x int], and add an enum 'packed' to MVT::ValueType (ValuesTypes.h). I declared all 'RegisterClass'es to be 'packed' (first argument of RegisterClass): def GeneralPurposeRC : RegisterClass<packed, 128, [R0, R1]>; def INT_ReadOnlyRC : RegisterClass<packed, 128, [I0, I1]>; def FP_ReadOnlyRC : RegisterClass<packed, 128, [F0, F1]>; def MOVgg : BinaryInst<0x51, ( ops GeneralPurposeRC :$dest, ope GeneralPurposeRC :$src), "mov $dest, $src">; def MOVgi : BinaryInst<0x52, ( ops GeneralPurposeRC :$dest, ope INT_ReadOnlyRC :$src), "mov $dest, $src">; def MOVgf : BinaryInst<0x52, ( ops GeneralPurposeRC :$dest, ope FP_ReadOnlyRC :$src), "mov $dest, $src">; In the instruction selector, SDOperand::getValueType() always returns 'MVT::packed' for all operands. I cannot distinguish between GeneralPurposeRC, INT_ReadOnlyRC, FP_ReadOnlyRC. But a correct register class is necessary for SSARegMap to create a virtual register. 2005/7/22, Misha Brukman <brukman at cs.uiuc.edu>:> On Fri, Jul 22, 2005 at 10:29:38AM +0800, Tzu-Chien Chiu wrote: > > I' have three set of registers - read-only regs, general purpose regs > > (read and write), and write-only regs. How should I partition them > > into different RegisterClasses so that I can easy define the > > instruction? > [snip] > > def MOV : BinaryInst<2, (ops GeneralPurposeRegClass :$dest, > > GeneralPurposeRegClass :$src), "mov $dest, $src">; > > > > There can be only one RegisterClass defined for each instruction > > operand, but actually the destition operand could be > > 'GeneralPurposeRegClass ' or 'WriteOnlyRegClass ', and the source > > operand can be 'ReadOnlyRegClass' or 'GeneralPurposeRegClass'. > > Presumably, when you write your instruction selector, you know when you > want to have a write-only vs. general purpose and read-only vs. general > purpose register. Some things are naturally read-only, such as status > registers that are only modified as a side effect of instructions (fp > errors, overflow, etc.) and some are write-only registers (I'm guessing > video and network cards have these for outputs). > > So a solution that may work for you would be to define permutations of > the instructions that explicitly specify what type of operands your > instruction takes (because different instructions need different LLVM > opcodes) but the instructions would print out the same, so in your > example: > > MOVgg : General, General > MOVwg : Write-only, General > MOVwr : Write-only, Read-only > > Note that if they all have the same "mov $dest, $src" print string, they > will be printed out identically, but you need to separate them anyway. > If you look at the X86 backend, you might find many flavors of MOV > instructions as well, but for a different reason. > > The best way is to lazily add permutations that you need as you go > along, so you don't have to convert your entire .td file(s) over to a > complete set of permutations immediately. > > Good luck, > -- > Misha Brukman :: http://misha.brukman.net :: http://llvm.cs.uiuc.edu >-- Tzu-Chien Chiu, 3D Graphics Hardware Enginner, <URL:http://www.csie.nctu.edu.tw/~jwchiu>
Maybe Matching Threads
- [LLVMdev] How to partition registers into different RegisterClass?
- [LLVMdev] How to partition registers into different RegisterClass?
- [LLVMdev] How to partition registers into different RegisterClass?
- [LLVMdev] How to partition registers into different RegisterClass?
- [LLVMdev] How to partition registers into different RegisterClass?