[LLVMdev] Compile function with limited set of registers? Jump to another function?

Joshua Warner joshuawarner32 at gmail.com
Mon Jan 31 13:39:31 PST 2011


Hi James,

I see the problem now.  You might look at VMKit (a Java VM build with the
LLVM JIT compiler)  - I would expect it uses a similar method for resolving
interface calls (the method, if I understand it correctly, is well-known in
the Java world).

I've CC'd the main dev behind VMKit - he might be able to lend some insight.

--Joshua

On Mon, Jan 31, 2011 at 2:24 PM, James Williams <junk at giantblob.com> wrote:

> Hi Joshua,
>
> Thanks - I was hoping that would be the case.
>
> However, I've had a think about this since I posted to the list and I
> believe the only way to handle these issues safely in LLVM IR would be to
> define the thunk as varargs. I'm not sure how well LLVM handles varargs but
> ideally it would all compile down to nothing since the parameters to the the
> thunk would be in the same registers/stack locations as required by the
> target method.
>
> Unfortunately, varargs has some downsides: there's the additional overhead
> for the extra hidden parameter to every interface method call for the
> parameter count plus it doesn't (I don't think) support tail calls.
>
> -- James
>
>
> On 27 January 2011 17:37, Joshua Warner <joshuawarner32 at gmail.com> wrote:
>
>> Hi James,
>>
>> I'm no expert in LLVM IR, but I think that just encoding each *actual*
>> method invocation in the thunk as a tail call would work.  This would
>> require trusting that LLVM passes / code generators will translate down to a
>> jump, as is normal.  If the passes / code generators are smart, I see no
>> reason that LLVM wouldn't emit code that fits your requirements.  Either
>> way, you know that your thunk will be correct - it just might not be as
>> efficient as you want.
>>
>> I would suggest experimenting with generating a thunk this way, and look
>> at the resultant target assembly to make sure it's doing what you want.
>>
>> -Joshua
>>
>>  On Tue, Jan 25, 2011 at 2:04 AM, James Williams <junk at giantblob.com>wrote:
>>
>>>  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
>>>
>>>
>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110131/356a77a4/attachment.html>


More information about the llvm-dev mailing list