How to finalize instruction lowering after register allocation.


I’ve some problems/questions while implementing the BUILD_VECTOR primitive for a SIMD microcontroller…

This microcontroller has two FPU units: UnitA and UnitB.

UnitA has a bank of 512 registers named RegisterA_0 … RegisterA_511.

UnitB has a bank of 512 registers named RegisterB_0 … RegisterB_511.

The FPU instruction format has a 2 bits operand indicating which units are involved: none, only UnitA, only UnitB, and the SIMD version UnitA and UnitB.

The SIMD version of a FPU instruction operates on registers with the same ID of both banks.

For examples:

FADD A R1, R2; // => ACC_A = RegisterA_1 + RegisterA_1

FADD B R5, R6; // => ACC_B = RegisterB_5 + RegisterB_6

FADD AB R7, R8; // => ACC_A = RegisterA_7 + RegisterA_8 and ACC_B = RegisterB_7 + RegisterB_8

From a machine registers definition point of view, I’ve first defined the 512 UnitA registers in a RegisterClass RegClassA and the 512 UnitB registers in a RegisterClass RegClassB.

In order to defined registers operands for the SIMD version of FPU instructions, I’ve then defined 512 registers in a RegisterClass RegClassAB.

The registers from RegClassAB overlap the one the ones of RegClassA and RegClassB in this way RegClassAB.R1 has two subregisters: RegClassA.R1 and RegClassB.R1.

So far, so good. I can generated code for math expression taking advantage of SIMD FPU!

My problem is on the implementation of the BUILD_VECTOR that should build RegClassAB register from a pair of RegClassA/RegClassB registers or constants.

For this purpose, I only have a MOV instruction operating either on UnitA or UnitB.

So from the BUILD_VECTOR, I have to generate two MOV instructions, one for the UnitA and UnitB.

Assuming that %vreg3 (of class RegClassAB) will be allocated to R22, %vreg3 = BUILD_VECTOR 2.7172, 3.1416 should be lowered into:

MOV A 2.7172, R22 ; // RegisterA_22 = 2.7172

MOV B 3.1416, R22; // RegisterB_22 = 3.1416

Generating the two instruction could be easily done by custom inserter at end of Instruction Selection.

It is understood that the MachineRegisterInfo has all the information about the sub-registers overlapping.

But the problem is have to map (before registers allocation) one Virtual Register of RegClassAB into the two overlapping physical sub-registers !

Has someone an idea to properly lowering and allocating registers to BUILD_VECTOR, considering my SIMD registers definition and my instructions set?

Thanks in advance, comments are welcome. Dominique Torette.

It would seem like a Pseudo for BUILD_VECTOR that would take the two values and produce a RegClassAB register is a good solution. Then you can catch it in expandPostRAPseudo and produce the MOV instructions. The register allocator will then allocate the wide register you need and you can safely use the subregisters for the two MOV instructions. I would imagine you’d want to make sure that the isRenamable flag isn’t set on the subregisters when you do that.

Hopefully this helps.