<div dir="ltr"><div><div>Hi Virgile,<br><br></div>You might be interested in the interop code I wrote for my <a href="http://LLVM.NET">LLVM.NET</a> binding: <a href="https://bitbucket.org/lost/llvm.net/src/d8014b07723c69571e188a453ab39c764252985c/LLVM/Interop/?at=default">https://bitbucket.org/lost/llvm.net/src/d8014b07723c69571e188a453ab39c764252985c/LLVM/Interop/?at=default</a><br><br></div>- Victor<br></div><div class="gmail_extra"><br><div class="gmail_quote">2014-12-30 23:41 GMT-08:00 Virgile Bello <span dir="ltr"><<a href="mailto:virgile.bello@gmail.com" target="_blank">virgile.bello@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello,<div><br></div><div>In my LLVM frontend (CLR/MSIL), I am currently using first-class aggregates to represent loaded value types on the "CLR stack".</div><div><br></div><div>However, I noticed that when calling external method taking those aggregate by value, they were not passed as I expected:</div><div><br></div><div>%COLORREF = type { i8, i8, i8, i8 }<br></div><div><br></div><div>declare i32 @SetLayeredWindowAttributes(i8*, %COLORREF, i8, i32)</div><div>I call this function with call x86_stdcallcc (it's a Win32 function, loaded with GetProcAddress)<br></div><div><br></div><div>However, checking the assembly code, it seems that the %COLORREF gets split due to the calling convention: first i8 field go through %edx, but the 3 next fields go through the stacks.</div><div>I would like all of it to go through either a single 32bit register or a 32bit stack value (since all of the structure fits in a i32 and it is already packed in memory that way before the call).<br></div><div><br></div><div>I was thinking using alloca with sret/byval might help, but I am not even sure since it is enough, since clang also seems to actually use i16 or i32 (and even i32+i16 or i32+i32) to represent such struct <= 8 bytes  when passing them to a method (even if they contain many smaller i8 fields).</div><div><br></div><div>Does somebody know if only alloca with sret/byval is enough or if I also need to concat myself smaller struct into i32 types like clang does to be sure it won't be split across registers?</div><div>Any other hint or idea on how I can achieve this?</div><div><br></div><div>Also, I was wondering which is the current recommendation (sret/byval with alloca for every copy vs first-class aggregate) considering the current state of LLVM and supported optimizations. Since clang uses sret/byval, I expect it to be more optimized/mature, but I might be wrong.</div><div><br></div><div>I suppose LLVM will easily understand/optimize all those additional aggregate alloca/memcpy I will end up doing if I were to switch to a sret/byval approach?</div><div><br></div><div>Thanks,<br></div></div>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div>