[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:
He pointed me to this earlier, thanks.
More information about the llvm-dev