This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

optimization/2399: 23 superflouis moves in a C++ function that needs 1



>Number:         2399
>Category:       optimization
>Synopsis:       23 superflouis moves in a C++ function that needs 1
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 26 21:46:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Scott Crosby
>Release:        gcc version 2.95.2 20000220 (Debian GNU/Linux)
>Organization:
>Environment:
Linux x86.  Compiled with -O3 -fomit-frame-pointer
>Description:
Compiled function grabs about 20 stack slots, fills them with stuff, and then never reads them. It replaces a 5-instruction function with 30.

00000090 <bar__FGQ2t13D3VolumeIndex2ZcZt13D3VolumeFixed4Zci16i16i16_5Index>:
  90:   83 ec 78                sub    $0x78,%esp
  93:   53                      push   %ebx
  94:   8b 9c 24 80 00 00 00    mov    0x80(%esp,1),%ebx
  9b:   89 5c 24 30             mov    %ebx,0x30(%esp,1)
  9f:   8b 8c 24 84 00 00 00    mov    0x84(%esp,1),%ecx
  a6:   89 4c 24 34             mov    %ecx,0x34(%esp,1)
  aa:   8b 94 24 88 00 00 00    mov    0x88(%esp,1),%edx
  b1:   89 54 24 38             mov    %edx,0x38(%esp,1)
  b5:   8b 84 24 8c 00 00 00    mov    0x8c(%esp,1),%eax
  bc:   89 44 24 3c             mov    %eax,0x3c(%esp,1)
  c0:   89 5c 24 44             mov    %ebx,0x44(%esp,1)
  c4:   89 4c 24 48             mov    %ecx,0x48(%esp,1)
  c8:   89 54 24 4c             mov    %edx,0x4c(%esp,1)
  cc:   89 44 24 50             mov    %eax,0x50(%esp,1)
  d0:   c7 44 24 54 05 00 00    movl   $0x5,0x54(%esp,1)
  d7:   00 
  d8:   89 5c 24 14             mov    %ebx,0x14(%esp,1)
  dc:   89 4c 24 18             mov    %ecx,0x18(%esp,1)
  e0:   89 54 24 1c             mov    %edx,0x1c(%esp,1)
  e4:   89 44 24 20             mov    %eax,0x20(%esp,1)
  e8:   89 5c 24 58             mov    %ebx,0x58(%esp,1)
  ec:   89 4c 24 5c             mov    %ecx,0x5c(%esp,1)
  f0:   89 54 24 60             mov    %edx,0x60(%esp,1)
  f4:   89 44 24 64             mov    %eax,0x64(%esp,1)
  f8:   c7 44 24 68 05 00 00    movl   $0x5,0x68(%esp,1)
  ff:   00 
 100:   c7 44 24 6c 04 00 00    movl   $0x4,0x6c(%esp,1)
 107:   00 
 108:   c6 80 45 03 00 00 0a    movb   $0xa,0x345(%eax)
 10f:   5b                      pop    %ebx
 110:   83 c4 78                add    $0x78,%esp
 113:   c3                      ret    


I am implementing my own type of homebrew arrays as a set of C++ classes, so I can do things like:

void bar (D3VolumeIndex<char,D3VolumeFixed<char,16,16,16> >::Index bar) {
  bar[5][4][3]=10;
}


I get the above code. I'm pretty sure I am paying the abstraction penalty highly here.

Is there a different way I can do this where I will not have to pay the abstraction overhead?


Code follows:


template <typename T> 
class D3VolumeVar {
 public:
  D3VolumeVar(int x, int y, int z): _x(x), _y(y), _z(z) {
    _data=new T[x*y*z];
  }

  int getXsize() { return _x; }
  int getYsize() { return _y; }
  int getZsize() { return _z; }
  
 public:
  T &get(int x, int y, int z) const {
    return _data[x+_x*y+_x*_y*z];
  }
  
 private: 
  const int _x,_y,_z;
  
  T *_data;
};


template <typename T, int X, int Y, int Z> 
class D3VolumeFixed {
 public:
  D3VolumeFixed() : D3VolumeFixed(X,Y,Z) {};
  D3VolumeFixed(int x, int y, int z): _x(x), _y(y), _z(z) {
    assert(X==x); assert(Y==y); assert(Z==z);
    _data=new T[x*y*z];
  };

  int getXsize() { return _x; }
  int getYsize() { return _y; }
  int getZsize() { return _z; }
  
 public:
  T &get(int x, int y, int z) const {
    return _data[x+X*y+X*Y*z];
  }
  
 private: 
  const int _x,_y,_z;
  
  T *_data;
};




template <typename T, class D3Volume>
class D3VolumeIndex {
  
  class Index;
  class XIndex;
  class YIndex;
  
  //template <typename T, class D3Volume>
  class Index {
  protected:
    D3Volume _volume;
  public:
    const XIndex operator[](int x) const {
      return XIndex(_volume,x);
    }
  };
  
  //template <typename T, class D3Volume>
  class XIndex {
  protected:
    D3Volume _volume;
    int _x;
  public:
    XIndex(D3Volume volume, int x): _volume(volume), _x(x) {};
    const YIndex operator[](int y) const{
      return YIndex(_volume,_x,y);
    }
  };
  


  //template <typename T, class D3Volume>
  class YIndex {
  protected:
    D3Volume _volume;
    int _x,_y;
  public:
    YIndex(D3Volume volume, int x, int y): _volume(volume), _x(x), _y(y) {};
    T &operator[](int z) const {
      return _volume.get(_x,_y,z);
    }
  };
  

};




void foo (D3VolumeIndex<char,D3VolumeVar<char> >::Index foo) {
  foo[17][34][51]=10;
}

void bar (D3VolumeIndex<char,D3VolumeFixed<char,16,16,16> >::Index bar) {
  bar[5][4][3]=10;
}

>How-To-Repeat:

>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]