Creating virtual register in XXRegisterInfo.cpp

When indexing a stack allocated array, I receive an offset in the eliminateFrameIndex() function in XXRegisterInfo.cpp where XX is a custom backend name.
Sometimes this offset is outside the range of immediate that can be issued to a direct stack pointer relative index.
In this case, I want to issue a register-register store/load and copy the immediate into a register. To do this, I create a VirtualRegister here and then I use the BuildMI function to create an add instruction that adds the immediate into the register.
However, this then runs into an error later on where the register issued has an index that’s outside the range of valid registers, and on debugging this number is something absurd like -2415678.

I’m wondering how to generate a virtual register in the eliminateFrameIndex() stage that gets allocated correctly later on?


This is a known situation. Look at the part of prolog/epilog insertion where it uses register scavenger to allocate such registers. You may need to reserve some number of emergency spill slots for use by the scavenger when you create the stack frame for your function.

Thanks for this. Managed to get it to work using RegisterScavenger.FindUnusedReg.

FindUnusedReg will fail if there are no available registers. You want to set up a scavenger with an emergency spill slot, and use scavengeRegister.

Alternatively, you can use requiresFrameIndexScavenging and create virtual registers (but this still requires a scavenger which may still need an emergency spill slot)

So I tried this at first, but what seemed to be happening was that it seemed to be trying to scavenge registers already used in the basic block that the instruction was in, but couldn’t find any as the basic block only used 1 or 2 registers. This meant that it always tried to spill. I’m not fully sure I’m understanding this behavior correctly, but after changing it to FindUnusedReg, it started working fine.

To then prevent spill when using scavengeRegisterBackwards, do I have to set the search space to multiple basic blocks before the instruction at which we would like to scavenge a register?