Hi,
Can anyone tell me, is it possible to express in LLVM IR:
- that, for a specific function, register allocator can use only limited set of registers? (specifically, cannot touch any registers that might contain parameters)
- that stack can’t be touched? (or at least must balance on exit from thunk)
- jump, not call, to another function leaving any received parameters unchanged in registers and on stack?
Thanks,
– James Williams
Background:
I’m looking for some advice on implementing thunks required by my language’s interface call mechanism. This is a fairly conventional arrangement where method selectors in interfaces are hashed to determine their index within a vtable and hash collisions are disambiguated at runtime by a thunk, which determines which method to call from a selector id passed as the first method parameter.
I’m currently using a single thunk (written in assembly) for all collisions that walks a table to determine what method to call. This works but it’s inefficient and requires the a hand written thunk for each supported target.
I’d like to instead generate IR for a specific thunk for each vtable collisoin that does a binary search of possible selectors because this will avoid some pointer dereferences and an additional indirect call.
The problem is that a thunk may need to decide between methods with different signatures without disturbing parameters in registers and on the stack and then jump to, rather than call, another function:
interface X:
method A(a, b)
interface Y:
method B(c, d, e)
class Z implements X, y:
method A(a, b) …
method B(c, d, e) …
X.A + Y.B happen to hash to same vtable index, say -3
This would require a thunk something like:
vtable[-3] =
thunk_Z_AorB(selector_id, …)
// binary search for matching selector id:
if selector_id <= selector_Z_A then
Z.A(selector_id, …)
else
Z.B(selector_id, …)
fi
which would ideally would compile on x64 to something like:
thunk_Z_AorB:
cmp $selector_Z_A, %rdi
jle Z.A
jmp Z.B