How to create unspillable live interval zone for a set of regs but not allocating them?

I have a scenario where given two instructions that are several instructions apart, certain registers cannot be allocated in the flow path between them for correct operation. I thought of a way to do this and it requires creating a live interval range between the two instructions and marking it as unspillable. Unfortunately, doing this without allocating the actual register(s) associated to live intervals seems like an uncanny situation (aren’t live intervals generated from registers?). I’m not sure if there is already an existing, recommended way to do this before RA, any help would be greatly appreciated.

You cannot guarantee a register will not spill. LiveInterval has markNotSpillable, but this is really an implementation detail of greedy that leaks out. Also, FastRegalloc does not use LiveIntervals at all and spills all live out values from a block.

Thought about it more and it seems like there should be multiple outputs for first instructions consumed by the second. Will give it a try.

This question pops from time to time. I also needed this functionality.
Consider the case when there is a call or an inline asm between the instructions that clobbers everything. Spills are unavoidable in such cases.

In my former target, we solved it my rematerializing the first instruction right before the second. This was done as a separate pass that runs after built-in register allocators. To ensure that the built-in register allocators do not allocate certain virtual registers, RegClassFilterFunc can be used.

1 Like