From: Jeffrey Yasskin on 2 Dec 2006 16:31 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 2 Dec 2006 16:30 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 2 Dec 2006 16:30 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 2 Dec 2006 16:58 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 2 Dec 2006 17:17
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! ] |