Hi,
Is there a canonical way to ensure a value will be in a specific register prior to a call? I’d like the intervening code to be able to reuse the register, so I’d like to avoid reserving it. The value is valid for the lifetime of the frame, but can likely be recomputed efficiently. Since the value isn’t needed except at call sites, I’d like to ensure that the register allocator, and any other optimizations can leverage this information.
As an example, assume on X86 that I’d like to use R11
as part of this protocol, but I’d still like to use it as a free register between calls. Which register it is, doesn’t matter, and I picked R11
rather arbitrarily since its a scratch register, but in practice it may actually end up being a callee saved reg (still TBD). I’d also like to do this for targets other than X86, so I’m after a general method rather than any specific advice regarding X86.
In the snippet below, the prologue executes normally, but we additionally use R11
before computing its new value in the callee. After the callee returns, R11
can be freely used again. Ideally the optimizer would decide if it should be loaded, spilled, or recomputed prior to the call to foo(...)
in BB2
. The callee foo()
may or may not participate in the protocol, but either way, we’d like R11
to hold the correct value at the call site.
prologue:
// Handle Callee saved regs, etc.
// use passed in R11
// compute new R11 value for current frame
// ... R11 can be used as a free register until the next CALL instruction
BB2:
// Marshall arguments (omitted)
// Rematerialize R11 for callee (may be recomputed, reloaded, or copied)
// Call foo(...)
// R11 is free again ...
I’m pretty sure there are many approaches that would work here, but this seems like a common enough task that I figured it would be best to just ask before running off and experimenting.
I did spend some time digging through CodeGen
and Target
but I haven’t found anything obvious yet. Most of my experience has been doing analysis and transforms on LLVM IR rather than modifying the backend, so I’m not familiar w/ many of the codegen and target specific transforms.
Any pointers here are very much appreciated.