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