suggestion: multiple results from function call.

Hello

A suggestion to LLVM (assembly) language designers.

It could be worthwhile to extend the LLVM language LLVM Language Reference Manual — LLVM 16.0.0git documentation so that calls may return more than one result (for example, Common lisp functions can return more than one result).
The intent could be to extend the ABI calling conventions to permit a function to return a few results (all in registers), instead of only one.

The trade-off is to keep all the results in registers. I would suggest to permit at most three (or perhaps four) results, with the implicit hypothesis that such a calling convention is compatible with all the processors I am aware of (the most register-starved is x86 in 32 bits mode, and it does have space for 3 or 4 registers used to return results, ie EAX, EBX, ECX and maybe EDX). Maybe this would require a specific calling convention (I forgot if in the usual C ABI, those registers are caller or callee saved).

Alternatively (this is what Common Lisp usually do) one could permit an arbitrary (but reasonably small) number of results, but this require a fall-back machinery when we are out of registers (spilling results on the call stack is probably mroe tricky than vararg implementation)

This would permit some advanced compilers using LLVM to return two or three pointers in registers, perhaps even (for hypothetically very clever compilers) in C or C++ return struct of 3 words in registers, not thru the stack, or some ML implementations returning a couple like (x,y) or triplet like (x,y,z) thru registers (without boxing the couple or triplet)

Even having at most 2 results, ie the primary result and an optional secondary one could be very useful (eg returning both the sine and cosine of a float, or the remainder and the quotient of two non-zero integers).

And the current processors have some registers that could be used to return (a few, 2 to 4) additional values without much harm, and probably faster than returning a structure on the stack.

My intuition is that permitting 2 or 3 results could be really useful (and fairly easy to implement), but more than that (eg 4 or more results) is probably almost useless and complex to implement.

And since LLVM does not have nested function calls (like f(g(x),h(x,y),z)) I would suppose that expanding the language to permit calls with 2 or 3 (maybe 4) results is not very hard (for experts of back end code generation).

Comments are welcome.

Regards.

It could be worthwhile to extend the LLVM language LLVM Language Reference Manual — LLVM 16.0.0git documentation so that calls may return more than one result (for example, Common lisp functions can return more than one result). The intent could be to extend the ABI calling conventions to permit a function to return a few results (all in registers), instead of only one.

Yes, I agree:
http://nondot.org/sabre/LLVMNotes/MultipleReturnValues.txt

The trade-off is to keep all the results in registers. I would suggest to permit at most three (or perhaps four) results, with the implicit hypothesis that such a calling convention is compatible with all the

The first step is to get the LLVM IR to support it. Based on that, each target can make the 'smart' decision about how to implement particular calls.

Alternatively (this is what Common Lisp usually do) one could permit an arbitrary (but reasonably small) number of results, but this require a fall-back machinery when we are out of registers (spilling results on the call stack is probably mroe tricky than vararg implementation)

Exactly. For example, the standard trick of passting in a pointer to the return area works.

This would permit some advanced compilers using LLVM to return two or three pointers in registers, perhaps even (for hypothetically very clever compilers) in C or C++ return struct of 3 words in registers, not thru the stack, or some ML implementations returning a couple like (x,y) or triplet like (x,y,z) thru registers (without boxing the couple or triplet)

Yep!

My intuition is that permitting 2 or 3 results could be really useful (and fairly easy to implement), but more than that (eg 4 or more results) is probably almost useless and complex to implement.

The 'hard' part is really to get the LLVM IR support for this in place.

Comments are welcome.

I'm certainly interested in having this in LLVM, we just haven't had anyone interested in implementing it yet. Are you? :slight_smile:

-Chris