[LLVMdev] How to partition registers into different RegisterClass?

Chris Lattner
Fri, 22 Jul 2005 19:06:39 -0000

On Fri, 22 Jul 2005, Tzu-Chien Chiu wrote:
> 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]>;

...

> 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.

What does a 'read only' register mean?  Is it a constant (e.g. returns
1.0)?  Otherwise, how can it be a useful value?

-Chris

>
>
> 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
>>
>
>
>

-Chris

--