[LLVMdev] Passing and returning aggregates (who is responsible for the ABI?)

Christophe de Dinechin christophe at dinechin.org
Mon Nov 5 23:27:25 PST 2007

On 6 nov. 07, at 01:35, Gordon Henriksen wrote:

>> But then, why refuse aggregates as input or output of a call? What
>> is the rationale?
> Probably in good part because, in LLVM, aggregates (or derived types)
> types exist only in memory, not in registers.

Thanks, that's precisely where I see a problem. On many recent  
architectures (Itanium being the extreme case), small enough  
aggregates are passed and held in registers. Thinking or designing  
"aggregates == memory" is an obsolete approach ;-) I like the "call"  
instruction because, at least, it got rid of the "arguments == push  
to stack" approach you find in the Java or MISL bytecodes...

As an aside, why do I care? I wanted XL to be efficient on modern  
architectures, so I got rid of "implicit memory accesses" as much as  
I could, e.g. no "this pointer". At one point, I compiled a simple  
program manipulating complex numbers to draw a Julia set. At the  
lowest level of optimization, the XL version was at least 70% faster  
than the C++ version.

Why? Because the user-defined complex operations in XL were all done  
in registers, whereas at that level of optimization, the C++ compiler  
was not doing the memory aliasing analysis required to perform  
"register field promotion", elimintate the "this pointer", and turn  
the C++ complex class into registers. In other words, a complex  
addition was 4 loads, two fp adds, and 2 stores for C++, as opposed  
to only the fp adds for XL. Obviously, an IR assuming that aggregates  
are in memory does not help here.

> Chris has some notes about how to do this for return values here:
> http://www.nondot.org/sabre/LLVMNotes/MultipleReturnValues.txt

He pointed me to this earlier, thanks.


More information about the llvm-dev mailing list