[Bug c++/12685] New: Compiler-generated copy constructor breaks optimization

Teddy dot Todorov at cern dot ch gcc-bugzilla@gcc.gnu.org
Mon Oct 20 11:16:00 GMT 2003


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12685

           Summary: Compiler-generated copy constructor breaks optimization
           Product: gcc
           Version: 3.3.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: Teddy dot Todorov at cern dot ch
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu

A simple class with three "double" data members and some arithmetic operations 
results in optimal executable code if a copy constructor is explicitly written, 
but if the copy constructor is omitted (and therefore generated by the 
compiler) the execution time of a simple test program is increased by a factor 
of four!  
This bug report may be related to bug 6880, but it may shed some additional 
light on the problem: 
  - the compiler is clearly able to optimize correctly a member-by-member copy       
constructor if it is explicitly written. 
  - the compiler-generated copy constructor should perform a member-by-member 
copy 
  - the compiler-generated copy constructor breaks optimization. 
 
The HEAD of cvs version as of today (20/10/2003) has the same behaviour 
 
To reproduce the problem the program below should be compiled and timed twice: 
c++ -O2 singlefile.cxx -DCOPY_CONSTRUCTOR; time ./a.out 
c++ -O2 singlefile.cxx ; time ./a.out 
On my PC the first execution takes 0.220 seconds, and the second 1.010 seconds 
The only difference between the two is the removal of the copy constructor from 
the class definition. 
------------------------------------------------------------------------ 
class Basic3DVector { 
public: 
 
#ifdef COPY_CONSTRUCTOR 
  // copy constructor from same type 
  Basic3DVector( const Basic3DVector & p) :  
    theX(p.x()), theY(p.y()), theZ(p.z()) {} 
#endif 
 
  /// construct from cartesian coordinates 
  Basic3DVector( const double& x, const double& y, const double& z) :  
    theX(x), theY(y), theZ(z) {} 
 
  double x() const { return theX;} 
  double y() const { return theY;} 
  double z() const { return theZ;} 
 
  Basic3DVector& operator+= ( const Basic3DVector& p) { 
    theX += p.x(); 
    theY += p.y(); 
    theZ += p.z(); 
    return *this; 
  }  
 
  Basic3DVector& operator-= ( const Basic3DVector& p) { 
    theX -= p.x(); 
    theY -= p.y(); 
    theZ -= p.z(); 
    return *this; 
  }  
 
  /// Scalar product, or "dot" product, with a vector of same type. 
  double dot( const Basic3DVector& v) const {  
    return x()*v.x() + y()*v.y() + z()*v.z(); 
  } 
 
private: 
  double theX; 
  double theY; 
  double theZ; 
}; 
 
// vector sum and subtraction of same types 
inline Basic3DVector  
operator+( const Basic3DVector& v1, const Basic3DVector& v2) { 
  return Basic3DVector(v1) += v2; 
} 
 
inline Basic3DVector 
operator-( const Basic3DVector& v1, const Basic3DVector& v2) { 
  return Basic3DVector(v1) -= v2; 
} 
 
// scalar product 
inline double operator*( const Basic3DVector& v1, const Basic3DVector& v2) { 
  return v1.dot(v2); 
} 
 
double vectorCompute3( const Basic3DVector& v1,const Basic3DVector& v2)  
{ 
  return (v1+v2)*(v1-v2); 
} 
 
#include <iostream> 
 
int main() { 
    typedef Basic3DVector Vector; 
    int N = 10000000; 
    double sum = 0; 
    for (int i=1; i<N; i++) { 
	double s(i); 
	Vector v1( s, 2*s, 3*s); 
	Vector v2( 0.8*s, 0.5*s, 0.3*s); 
	sum += vectorCompute3(v1, v2);  
    } 
    std::cout << "sum = " << sum << std::endl; 
}



More information about the Gcc-bugs mailing list