[LLVMdev] Broke my tail (call)

Arnold Schwaighofer arnold.schwaighofer at gmail.com
Tue Feb 24 06:54:12 PST 2009


On Tue, Feb 24, 2009 at 11:50 AM, Jon Harrop <jon at ffconsultancy.com> wrote:

> Thanks for the clarification. That makes a lot more sense!
>
> LLVM's support for structs is wonderful but I don't think they can be
> called "first-class structs" until all such arbitrary restrictions have been
> removed, even though the workaround (using sret form) is trivial in this
> case.
>
> Shall I file this as a bug against LLVM?
Yes please do and maybe include the following code which already
exhibits the error in the bug report.

define fastcc { { i8*, i8* }*, i8*} @init({ { i8*, i8* }*, i8*}, i32) {
entry:
      %2 = tail call fastcc { { i8*, i8* }*, i8* } @init({ { i8*,
i8*}*, i8*} %0, i32 %1)
      ret { { i8*, i8* }*, i8*} %2
}

> Assuming this gets fixed, will it be more efficient that the sret form?
Don't expect this to be fixed soon as i am currently on a leave of
absence from llvm busy with bringing tail calls to another vm and
writing a thesis about it ;).

Whether it will be more efficient i can't answer off hand. Sorry. But
probably not  because the code generated should be quite similar.

For the sret version the move of the result is performed before the return.
  store { i8*, i8* } %15, { i8*, i8* }* %19
  ret i32 0

For the struct return version this would be performed as part of
moving the result from the result registers to whatever virtual
register is expecting the result. If the register allocator decides to
merge the virtual register with the result registers than no further
move is needed.
%2 = tail call fastcc { { i8*, i8* }*, i8* } @init({ { i8*, i8*}*,
i8*} %0, i32 %1)

Note that if you have a series of sequential recursive tail calls this
move will only performed once (at the bottom of the recursion,
respectively when the recursion returns) so it's impact on performance
should be minimal.

regards
arnold



More information about the llvm-dev mailing list