[LLVMdev] How to partition registers into different RegisterClass?
Tzu-Chien Chiu
tzuchien.chiu at gmail.com
Mon Jul 25 02:38:37 PDT 2005
Thanks, I think it can solve my problem.
But please allow me to explain the hardware in detail. Hope there is
more elegant way to solve it.
The hardware is a "stream processor". That is, It processes samples
one by one. Each sample is associated with several 128-bit
four-element vector registers, namely:
* input registers - the attributes of the sample, the values of the
registers are different and initialized for each sample before
execution. READ-ONLY (can only be declared once by 'dcl' instruction).
* constant registers - sample-invariant. READ-ONLY (can only be
defined once by 'def' instruction). All samples shares the same set of
constant register values.
* general purpose registers - values are not initialized before the
execution and destroyed after execution. They can be read and written.
* output registers - WRITE-ONLY.
Sample program converted to pseudo-LLVM assembly (SSA):
%Vec4 = type < 4 x float>
// declare input registers and
// define constant register values
%v1 = dcl %Vec4 xyz
%v2 = dcl %Vec4 color
%c1 = def %Vec4 <1,2,3,4>
// v1, v2, c1 are not allowed to be destination register
// of any instruction hereafter.
%r1 = add %Vec4 v1, c1
%r2 = mul %Vec4 v1, c2
%o1 = mul %Vec4 r2, v2 // write the output register 'o1'
I planed to partition the register into different RegisterClass:
input, output, general purpose, constant, etc.
def GeneralPurposeRC : RegisterClass<packed, 128, [R0, R1]>;
def InputRC : RegisterClass<packed, 128, [V0, V1]>;
def ConstantRC : RegisterClass<packed, 128, [C0, C1]>;
def ADDgg : BinaryInst<0x51, (
ops GeneralPurposeRC :$dest,
ope GeneralPurposeRC :$src), "add $dest, $src">;
def ADDgi : BinaryInst<0x52, (
ops GeneralPurposeRC :$dest,
ope InputRC :$src), "add $dest, $src">;
def ADDgc : BinaryInst<0x52, (
ops GeneralPurposeRC :$dest,
ope ConstantRC :$src), "add $dest, $src">;
The problem is: SDOperand alwasy return the 'type' of the value (in
this case, 'packed', the first argument of RegisterClass<>), but not
the 'RegisterClass'. With two 'packed' operands, the instruction
selector doesn't know whether a ADDgg, ADDgi, or an ADDgc should be
generated (BuildMI() function).
The same problem exists when there are two types of costant registers,
floating point and integer, and each is declared 'packed' ([4xfloat]
and [4xint]). The instruction selector doesn't know which instruction
it should produce because the newly defined MVT type 'packed' is
always used for all operands (registers), even if it's acutally a
[4xfloat] or [4xint].
2005/7/24, Chris Lattner <sabre at nondot.org>:
> On Sat, 23 Jul 2005, Tzu-Chien Chiu wrote:
> > 2005/7/23, Chris Lattner <sabre at nondot.org>:
> >> What does a 'read only' register mean? Is it a constant (e.g. returns
> >> 1.0)? Otherwise, how can it be a useful value?
> >
> > Yes, it's a constant register.
> >
> > Because the instruction cannot contain an immediate value, a constant
> > value may be stored in a constant register, and it's defined _before_
> > the program starts by API. For example:
> >
> > SetConstantValue( 5, Vector4( 1, 2, 3, 4 ); // C5 = <1,2,3,4>
> > HANDLE handle = LoadCodeFromFile( filename );
> > SetCode( handle ); // C5 is referenced here
> > Execute();
>
> Ah, ok. In that case, you want to put all of the registers in one register
> file, and not make the constant register allocatable (e.g. see
> X86RegisterInfo.td, and note how the register classes include EBP and ESP,
> but do not register allocate them (through the definition of
> allocation_order_end()).
>
> -Chris
>
> --
> http://nondot.org/sabre/
> http://llvm.org/
>
--
Tzu-Chien Chiu,
3D Graphics Hardware Enginner,
<URL:http://www.csie.nctu.edu.tw/~jwchiu>
More information about the llvm-dev
mailing list