From: Jeffrey Yasskin on
On Nov 30, 7:27 am, Gabriel Dos Reis <g...(a)integrable-solutions.net>
wrote:
> The Itanium Software Conventions and Runtime Architecture Guide
> specifies (page 8-13) that certain aggregates are returned in
> registers. That is lift to C++ UDT if they don't have non-trivial
> *copy-constructor* or *destructor*. See the "common C++ ABI"
> specification
>
> http://www.codesourcery.com/cxx-abi/abi.html#calls
>
> In general, C++ return values are handled just like C return
> values. This includes class type results returned in
> registers. However, if the return value type has a non-trivial copy
> constructor or destructor, the caller allocates space for a
> temporary, and passes a pointer to the temporary as an implicit first
> parameter preceding both the this parameter and user parameters. The
> callee constructs the return value into this temporary.

Since std::complex has a non-trivial copy constructor (well, actually
it can be trivial; libstdc++ in gcc 4.0.0 does it...), it can't be
returned in registers on the Itanium. Are there any ABIs that allow it?
I know very little about ABI design, but I'd guess that it's very
tricky to specify that a compiler must implement a particular level of
optimizations on an interface boundary. Walter's opportunity is to
define a language feature that would let a library writer help the
compiler pass and return UDTs in registers even when the copy
constructor is non-trivial, and do it uniformly enough to specify in
the ABI.

Jeffrey


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Walter Bright on
Walter Bright wrote:
> ------------- C++ ------------------
> struct Foo { int x; };
>
> Foo bar(int i)
> {
> Foo f;
> f.x = i;
> return f;
> }
> ------------------------------------

I should add, compiling the above program with the D compiler gives:

_D5test23barFiZS5test23Foo comdat
ret

It's hard to see how that could be improved. (The D function calling
convention passed the struct in register EAX.)

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Gabriel Dos Reis on
Walter Bright <walter(a)digitalmars-nospamm.com> writes:


| Furthermore, your ABI quotes are clear that if a type has a non-trivial
| constructor (which std::complex has), it cannot be passed/returned in
| registers.

You're wrong. Please, read carefully. The ABI says that if a type has
non-trivial *copy* constructor or a destructor, it cannot be passed or
return in a registers. Please be careful in your reading.

And, GCC's std::complex specializations for float, double, and long
double have trivial copy-constructors. So does the primary template.



--
Gabriel Dos Reis
gdr(a)integrable-solutions.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Gabriel Dos Reis on
Walter Bright <walter(a)digitalmars-nospamm.com> writes:

| Gabriel Dos Reis wrote:
| > Fortunately, not all compilers out there made the decision to actively
| > unsupport abstractions like the Digital Mars compiler.
|
| Name one that returns std::complex values in a register pair.

I did in the part that was consciously left out from your reply.

GCC/g++.

Given

#include <complex>

std::complex<double>
add(std::complex<double> x, std::complex<double> y)
{
return x + y;
}

It produces, for a target that identifies itself as x86_64-suse-linux,

_Z3addSt7complexIdES0_:
.LFB1756:
addsd %xmm3, %xmm1
addsd %xmm2, %xmm0
ret

--
Gabriel Dos Reis
gdr(a)integrable-solutions.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Jeffrey Yasskin on
On Dec 2, 12:04 am, "Andrei Alexandrescu (See Website For Email)"
<SeeWebsiteForEm...(a)erdani.org> wrote:
> To be honest, the first problem I've had in my Java apps was that it's
> slow like molasses running uphill on a cold day in rough terrain for
> what I'm doing in my research. Our lab actually has a ban against
> running Java or much Perl on the computing cluster, because it just
> wastes precious resources. Perhaps they could be talked into allowing D :o).

My impression has always been that undefined (and unspecified) behavior
exist for performance reasons. C++ doesn't require array indexing to be
checked because it was believed to take too much time. It says
(roughly) that accessing the same memory through two different types is
undefined to help compilers with their alias analysis, which helps
optimization. Java may be slower precisely because it does define more
behavior.

Some of the existing undefined behaviors may no longer be necessary, of
course, but it seems silly to attack undefined behavior without first
measuring the performance benefits it gives you, including on minority
platforms. There's always Posix to define more behavior on common
platforms.

Jeffrey


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]