What is the correct procedure for translating a function signature from a high-order language to LLVM? It looks like I replace each struct/array parameter with a 'byval' pointer parameter, and I replace a result struct/array with an 'sret' pointer parameter. The reason I ask is that each calling convention has subtle variations for each architecture and platform. For example, cdecl in Win32 returns small (8 bytes or less) structures in EAX or EAX:EDX; whereas, cdecl in Linux always returns structures "in memory" (Source: http://www.programmersheaven.com/2/Calling-conventions). Does LLVM handle all of these nuances for me? Thanks, Jon
Hi Jon,> What is the correct procedure for translating a function signature from > a high-order language to LLVM?you have to do it carefully so that LLVM will end up producing object code that conforms to the platform ABI. For example, suppose you are using cdecl with a small struct (a pair of ints, say). Then your function should get two integer parameters, which LLVM will assign to registers. If using a large struct then use byval which will pass it on the stack. I know this is painful, hopefully LLVM will get some helpers for this one day. The reason is that some ABIs make distinctions that don't exist at the LLVM level. For example at least one ABI says that "complex" ( { double, double } ) should be passed differently to a struct containing a pair of doubles.> It looks like I replace each > struct/array parameter with a 'byval' pointer parameter, and I replace a > result struct/array with an 'sret' pointer parameter.No, it's not so easy, sorry.> The reason I ask > is that each calling convention has subtle variations for each > architecture and platform. For example, cdecl in Win32 returns small (8 > bytes or less) structures in EAX or EAX:EDX; whereas, cdecl in Linux > always returns structures "in memory" (Source: > http://www.programmersheaven.com/2/Calling-conventions). Does LLVM > handle all of these nuances for me?No it doesn't. Best wishes, Duncan.
Duncan Sands wrote:> Hi Jon, > >> What is the correct procedure for translating a function signature from >> a high-order language to LLVM? > > you have to do it carefully so that LLVM will end up producing object code > that conforms to the platform ABI. For example, suppose you are using cdecl > with a small struct (a pair of ints, say). Then your function should get two > integer parameters, which LLVM will assign to registers. If using a large > struct then use byval which will pass it on the stack. > > I know this is painful, hopefully LLVM will get some helpers for this one > day. The reason is that some ABIs make distinctions that don't exist at > the LLVM level. For example at least one ABI says that "complex" > ( { double, double } ) should be passed differently to a struct containing > a pair of doubles.Ugh, this isn't what I wanted to hear. Passing "complex" differently than a structure containing two doubles is a bad design, but alas, calling conventions are beyond our control. How many special cases like this are there? If "complex" is the only special case, LLVM could provide a complex type, which behaves like {double,double} in all respects except for calls. I recommend handling calling conventions entirely in the back end. Apart from calling conventions, the front end doesn't need to know the specific target, only the data layout and which intrinsics the target supports. This approach makes a clean division between the front end and back end. Best Regards, Jon
On Apr 12, 2008, at 3:22 PM, Jon Sargeant wrote:> What is the correct procedure for translating a function signature > from > a high-order language to LLVM? It looks like I replace each > struct/array parameter with a 'byval' pointer parameter, and I > replace a > result struct/array with an 'sret' pointer parameter. The reason I > ask > is that each calling convention has subtle variations for each > architecture and platform. For example, cdecl in Win32 returns > small (8 > bytes or less) structures in EAX or EAX:EDX; whereas, cdecl in Linux > always returns structures "in memory" (Source: > http://www.programmersheaven.com/2/Calling-conventions). Does LLVM > handle all of these nuances for me? >While other people have pointed out some of the intricacies involved in ABI compliance, I'd just like to point that you only need to be concerned with this if you're trying to interoperate with C/C++. If you're making the function signatures for use entirely with your own language, then none of this matters. You're free to invent your own calling convention and, as long as you apply it consistently, everything will work. --Owen