Finding live registers at a specific point in a MachineFunction and spilling them

Hi,

I'm trying to implement my ideas about better garbage collection
support [1]. The hardest problem seems to be to find all registers that
are live at safe points (for example, during a call) and spilling them.
Since nobody responded on the original thread, I decided to start a new
thread specifically for this question.

The problem is to safe registers that contain gc pointers to the stack
before a call and reload them after the call. Is there an Analysis Pass
that computes information about which registers are live during a
specific instruction? I looked at LiveIntervals and LiveVariables, but
they seem to be for cases when the pass knows the register and wants to
find the points where it is live. My code knows the point and wants to
find the registers that are live.

Another part of the problem is to spill the registers to the stack. Do
you think this is possible with the existing register spilling code?

-Manuel

[1] http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-July/064408.html

The problem is to safe registers that contain gc pointers to the stack
before a call and reload them after the call. Is there an Analysis Pass
that computes information about which registers are live during a
specific instruction? I looked at LiveIntervals and LiveVariables, but
they seem to be for cases when the pass knows the register and wants to
find the points where it is live. My code knows the point and wants to
find the registers that are live.

I've been doing something similar using the RegisterScavenger class. However, I'm no LLVM expert (yet), so that may not be the best way.

Another part of the problem is to spill the registers to the stack. Do
you think this is possible with the existing register spilling code?

I would also be interested to know if anyone has adapted the existing register spilling code for other uses. Didn't seem very flexible to me at first glance.

- Stephen

I don’t know about using the register scavenger, but if the only problem is calls then why not change your calling convention to save all registers? Then the register allocation will just do the right thing.

If there are other points you must save GC pointers, and you can identify them all prior to register allocation, then you can emit a pseudo NOP tagged to use all the registers which could possibly contain these pointers.

Of course this is overly pessimistic as it spills all non-pointer values too, but it might be enough to work with. And if you really want you could always have the calling convention only trash the upper half of the x86 registers. Pointers would still be spilled as they need a full 64-bits, but smaller expressions like ints could live across the calls in the lower 32-bits.

Pete