Howto avoid temporaries instantiated fully?

Richard Guenther rguenth@tat.physik.uni-tuebingen.de
Fri Mar 1 05:47:00 GMT 2002


Hi!

While designing an iterator for iterating a 3d grid for
numerical physics, I stumbled over the problem, that gcc
fully instantiates a temporary for an operator like
[full compilable example attached, compile with g++ -S -O3 and
see the difference in output for both methods]

Iterator operator+(int i) const {
  Iterator it(*this);
  it.m_i += i;
  return it;
}

even if only the (updated) m_i field of the new instance
is used (read once) in uses like

  array(i+1);

which is optimized ok if written as (ugly) array(i,+1) and
defining

  double& operator(const Iterator& i, int d) { return a[i.m_i+d]; }

which the compiler should be able to guess.

Is there a way to make the compiler optimize away this local
temporary class instance?

Please CC me, I'm not on the list.

Richard.

--
Richard Guenther <richard.guenther@uni-tuebingen.de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/
The GLAME Project: http://www.glame.de/
-------------- next part --------------

class Iterator {
public:
  Iterator(int i0, int i1)
    : m_i0(i0), m_i1(i1)
  {
    m_i = i0;
  }

  Iterator operator+(int i) const {
    Iterator it(*this);
    it.m_i += i;
    return it;
  }
  Iterator operator-(int i) const {
    Iterator it(*this);
    it.m_i -= i;
    return it;
  }

  bool operator++()
  {
    m_i++;
    if (m_i > m_i1)
      return false;
    return true;
  }

  int getIndex() const { return m_i; }

private:
  const int m_i0, m_i1;
  int m_i;
};

class Array {
public:
  Array(int size)
    : m_v(new double(size)) {}
  ~Array() { delete m_v; }

  double& operator()(const Iterator& i) { return m_v[i.getIndex()]; }
  double& operator()(const Iterator& i, int d) { return m_v[i.getIndex()+d]; }

private:
  double * const m_v;
};


int main(int argc, char **argv)
{
  Array a(256);
  Array b(256);
  Array c(256);

  {
    Iterator i(1, 254);
    __asm__ __volatile__("nop;nop;nop;nop" : :);
    do {
      __asm__ __volatile__("nop;nop;nop;nop" : :);
      a(i) = (b(i-1)+b(i+1))*c(i);
      __asm__ __volatile__("nop;nop;nop;nop" : :);
    } while (++i);
    __asm__ __volatile__("nop;nop;nop;nop" : :);
  }

  {
    Iterator i(1, 254);
    __asm__ __volatile__("nop;nop;nop;nop" : :);
    do {
      __asm__ __volatile__("nop;nop;nop;nop" : :);
      a(i) = (b(i,-1)+b(i,+1))*c(i);
      __asm__ __volatile__("nop;nop;nop;nop" : :);
    } while (++i);
    __asm__ __volatile__("nop;nop;nop;nop" : :);
  }
}



More information about the Gcc mailing list