[LLVMdev] About JIT by LLVM 2.9 or later

空明流转
Wed, 02 Nov 2011 01:12:51 -0000

Hello guys,

     Thanks for your help when you are busing.
     I am working on an open source project. It supports shader language
and I want JIT feature, so LLVM is used.
     But now I find the ABI & Calling Convention did not co-work with MSVC.
For example, following code I have:

struct float4 { float x, y, z, w; };
struct float4x4 { float4 x, y, z, w; };

float4 fetch_vs( float4x4* mat ){ return mat->y; }

Caller:

// ...
float4x4 mat; // Initialized
float4 ret = fetch(mat); // fetch is JITed by LLVM
float4 ret_vs = fetch_vs(mat)
// ...

Callee(LLVM):

%vec4 = type { float, float, float, float }
%mat44 = type { %vec4, %vec4, %vec4, %vec4 }
define %vec4 @fetch( %mat44* %m ) {
       %matval = load %mat44* %m
       %v2 = extractvalue %mat44 %matval, 2
       ret %vec4 %v2
 }

     But if it is implemented by LLVM and called the JIT-ed function in
MSVC, the program will be *crashed*.
     I traced into the implementations, ASMs are:

*    Caller:*

        float4x4 f;
        float4 b = fetch(&f);
    // Calling function. first address is a temporary result generated by
caller. And secondary is the &f.
    013C1428  lea         eax,[ebp-48h]
    013C142B  push        eax
    013C142C  lea         ecx,[ebp-138h]
    013C1432  push        ecx
    013C1433  call        fetch (13C11D6h)
    013C1438  add         esp,8

    // Copy result to another temporary vairable.
    013C143B  mov         edx,dword ptr [eax]
    013C143D  mov         dword ptr [ebp-150h],edx
    013C1443  mov         ecx,dword ptr [eax+4]
    013C1446  mov         dword ptr [ebp-14Ch],ecx
    013C144C  mov         edx,dword ptr [eax+8]
    013C144F  mov         dword ptr [ebp-148h],edx
    013C1455  mov         eax,dword ptr [eax+0Ch]
    013C1458  mov         dword ptr [ebp-144h],eax
    013C145E  mov         ecx,dword ptr [ebp-150h]

    // Copy secondary temporary to variable 'b'
    013C1464  mov         dword ptr [ebp-60h],ecx
    013C1467  mov         edx,dword ptr [ebp-14Ch]
    013C146D  mov         dword ptr [ebp-5Ch],edx
    013C1470  mov         eax,dword ptr [ebp-148h]
    013C1476  mov         dword ptr [ebp-58h],eax
    013C1479  mov         ecx,dword ptr [ebp-144h]
    013C147F  mov         dword ptr [ebp-54h],ecx

*    Callee( 'fetch_vs' MSVC ):*

      float4 __cdecl fetch( float4x4* mat ){

// Stack protection
002C13B0  push        ebp
002C13B1  mov         ebp,esp
002C13B3  sub         esp,0C0h
002C13B9  push        ebx
002C13BA  push        esi
002C13BB  push        edi
002C13BC  lea         edi,[ebp-0C0h]
002C13C2  mov         ecx,30h
002C13C7  mov         eax,0CCCCCCCCh
002C13CC  rep stos    dword ptr es:[edi]
        return mat->y;

// Copy to address of first temporary variable.
002C13CE  mov         eax,dword ptr [mat]
002C13D1  add         eax,10h
002C13D4  mov         ecx,dword ptr [ebp+8]
002C13D7  mov         edx,dword ptr [eax]
002C13D9  mov         dword ptr [ecx],edx
002C13DB  mov         edx,dword ptr [eax+4]
002C13DE  mov         dword ptr [ecx+4],edx
002C13E1  mov         edx,dword ptr [eax+8]
002C13E4  mov         dword ptr [ecx+8],edx
002C13E7  mov         eax,dword ptr [eax+0Ch]
002C13EA  mov         dword ptr [ecx+0Ch],eax
002C13ED  mov         eax,dword ptr [ebp+8]
    }
002C13F0  pop         edi
002C13F1  pop         esi
002C13F2  pop         ebx
002C13F3  mov         esp,ebp
002C13F5  pop         ebp
002C13F6  ret

    *Callee( 'fetch' LLVM ):*

010B0010  mov         eax,dword ptr [esp+4]
010B0014  mov         ecx,dword ptr [esp+8]
010B0018  movss       xmm0,dword ptr [ecx+1Ch]
010B001D  movss       dword ptr [eax+0Ch],xmm0
010B0022  movss       xmm0,dword ptr [ecx+18h]
010B0027  movss       dword ptr [eax+8],xmm0
010B002C  movss       xmm0,dword ptr [ecx+10h]
010B0031  movss       xmm1,dword ptr [ecx+14h]
010B0036  movss       dword ptr [eax+4],xmm1
010B003B  movss       dword ptr [eax],xmm0
010B003F  ret         4                                           // There
are nothing push/pop in function and stack space is managed by caller, so
why ret 4 is generated?

It will cause the stack unbalance before and after function call. the other
code look like well.

*Following is my questions:*

1. Why it generates "ret 4" but not "ret" without modify
esp?
2. Does it doesn't support Microsoft Visual C++ compiler directly ?
3. I want to integrate LLVM JIT in MSVC, is it possible? what I will do,
such as generate a adapter function ? Any porting document for it?
4. Does Clang support MS's call convention? If it does, how it work? I
traced into it, but code is too large.
5. Does it support Mingw directly ?
6. Does x64 work if your solution is applied ?

Thank you very much !

Best regards,
Your fans: Ye
--
Ye Wu
CELL: +86 13671730301
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20111102/11b57b53/attachment.html>