instructions requiring specific physical registers for operands

Hi,

I have som instructions that require the operand to be placed in exactly one physical register, and thus I have introduced a Just_a0 register class.

I have found that the register allocators / coalescer do not seem to care about this. In many cases they “run out of registers during register allocation”. I have managed to avoid some problems, by inserting target move instructions in and out of this Just_a0 register class.

I wonder, what would be the best solution for instructions that require operands in a particular register, and even gives the result in a particular register?

/Jonas

Hello Jonas,

I wonder, what would be the best solution for instructions that require
operands in a particular register, and even gives the result in a particular
register?

You need to custom select such instruction. See e.g. div / idiv on x86
as an example.

That's often easiest, yes; however, if they're normal allocatable registers, you may be able to define a register class containing only the fixed register then defining the instruction(s) using those as operands.

Something like, for a 32-bit register for target FOO:
def GPRr0 : RegisterClass<"FOO", [i32], 32, (add R0)>;
def GPRr1 : RegisterClass<"FOO", [i32], 32, (add R1)>;
def GPRr2 : RegisterClass<"FOO", [i32], 32, (add R2)>;

The an instruction that uses R0 and R1 as fixed input registers and R2 for output could define itself using those register classs:
def myInst : baseclass<…, (outs GPRr2:$dst), (ins GPRr0:$src1, GPRr1:$src2), …>
Use those reg classes in pattern to match also, and things should just work. The register allocator can take care of any reg-to-reg copies that are required.

-Jim

Jim,

The an instruction that uses R0 and R1 as fixed input registers and R2 for output could define itself using those register classs:
def myInst : baseclass<…, (outs GPRr2:$dst), (ins GPRr0:$src1, GPRr1:$src2), …>
Use those reg classes in pattern to match also, and things should just work. The register allocator can take care of any reg-to-reg copies that are required.

As far as I understand Jonas, this does not work in his case...

Thanks for the answers. The problems I have with using reg classes containing just the desired register, eg GPRr1RegClass can look like:

%vreg1 = COPY %a0 //arg
%vreg2 = COPY %a1 //arg
%vreg3:Just_a1 = COPY %vreg1

is rewritten by the coalescer to

%vreg3:just_a1 = COPY %a0
%vreg2 = COPY %a1

That is, the write of a1 is moved above a read of a1, and RA runs out of regs.

%vreg2:GPR = COPY %vreg0
%vreg3:GPR = COPY %vreg1
%vreg4:GPRr1 = COPY %vreg2
%vreg10 = div %vreg4, ...
%vreg5:GPRr1 = COPY %vreg3
%vreg11 = div %vreg5, ...

The RegCoalescer turns this into:

%vreg4:GPRr1 = COPY %vreg0
%vreg5:GPRr1 = COPY %vreg1
%vreg10 = div %vreg4, ...
%vreg11 = div %vreg5, ...

, and RA runs out of registers, because the coalescer is not aware of this consequence.

When the def-operand is required in such a reg-class:

%vreg1:GPRr1 = udiv ...
%vreg2:GPRr1 = COPY %vreg3
%vreg9 = div %vreg2
%vreg10 = div %vreg1

The udiv instruction can only return in a particular register, and the RA will run out of registers in cases like this.

So, it seems that the reg-coalescer is not conservative enough in cases with singular regclasses. I have handled these cases in preRA by rewriting to target-copy instructions where necessary, and I have also inserted target copies out of such regclasses (for def-operands), to avoid running out of regs.

Will these problems go away by COPYing into pregs in DAGtoDAG and using imp-use operands for these instead of the GPRr?RegClass Operands?

Jonas