<div dir="ltr">+David, Doug, Tim<div><br></div><div>I've implemented this forwarding for x86 / x86_64.</div><div><br></div><div>The one target I know about where varargs are passed differently from normal arguments is aarch64-apple-ios/macosx. After thinking a bit more, I think this forwarding thunk representation works fine even on that target. Typically a forwarding thunk is called indirectly, or at least through a bitcast, so the LLVM IR call site would look like:</div><div><br></div><div>define i32 @forwarding_thunk_caller() {</div><div>  %r = call i32 (%struct.Foo*, i64, i8)* bitcast (void (i8*, ...)* @adjustor_thunk to i32 (%struct.Foo*, i64, i8)*) (%struct.Foo* null, i64 42, i8 13)</div><div>  ret i32 %r<br>}</div><div><br></div><div>The thunk will have a varargs prototype, but it will also arrange to forward the unconsumed register parameters through to the musttail call site. I haven't implemented this yet for non-x86 architectures, but I plan to soon.</div><div><br></div><div>Does anyone object to this representation?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 2, 2014 at 3:54 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I needed this functionality to solve <a href="http://llvm.org/PR20653" target="_blank">http://llvm.org/PR20653</a>, but it obviously has far more general applications.</div><div><br></div><div>You can do it like this:</div>
<div><br></div><div>define i32 @my_forwarding_thunk(i32 %arg1, i8* %arg2, ...) {</div><div>  ... ; define new_arg1 and new_arg2</div><div>  %r = musttail call i32 (i32, i8*, ...)* @the_true_target(i32 %new_arg1, i8* %new_arg2, ...)</div>
<div>  ret i32 %r<br>}</div><div><div>declare i32 @the_true_target(i32, i8*, ...)</div></div><div><br></div><div>The varargs convention (usually) matches the standard function call convention, and everything will line up if you do an indirect call like this:</div>
<div><br></div><div>declare i32 @the_true_target(%struct.Foo* %this, i64, i8)</div><div>define i32 @my_forwarding_thunk(%struct.Foo* %this, ...) {</div><div>  %fptr = ... ; Compute fptr by bitcasting @the_true_target to the varargs type</div>
<div>  %r = musttail call i32 (%struct.Foo*, ...)* %fptr(%struct.Foo* %this, ...)</div><div>  ret i32 %r<br>}</div><div><br></div><div>Currently this functionality is only implemented for x86 in the absence of inreg and for x86_64 in the general case, but I'd like to see it implemented for the CPU backends. I'm happy to do some of them, but I don't have the time to do all of them.</div>
<div><br></div><div>Alternatively, it would be great if we could handle forwarding of unused register parameters in variadic functions in a general way. Perhaps CCState should surface this information.</div><div><br></div>
<div>Thoughts? This seemed like a reasonable way to represent such thunks, but I'd like to know if there are objections.</div><div></div></div>
</blockquote></div><br></div>