This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC] Contributing tree-ssa to mainline
Diego Novillo wrote:
> On Fri, 2004-01-16 at 22:24, Richard Kenner wrote:
>
> > Remember that the last time we had the discussion of the timing of tree-ssa,
> > people claimed it was "essential" for 3.5 since there was a tremendous
> > improvement on some C++ cases. So let's see those cases.
> >
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12747
I've been toying with boost::tie() lately, and the temporary tuple is
still *not* eleminated in the interesting cases, unfortunately.
For an example, look at the code generated for bar(foo&) and baz(foo&)
below, which should be quite similar once the template metaprogram has
been expanded. However, in the template case, indirection through
references still clutters the generated machine code.
We can do better; bar_neg(foo&) and baz_neg(foo&) show this. The
template version results in identical code in this case, except that
unnecessary space is allocated on the stack. (However, this
optimization happens on mainline, too, not just on the branch.)
(Probably this is a different issue, but I had hoped that the tree-ssa
branch would somehow improve things in this area.)
#include <boost/tuple/tuple.hpp>
struct foo {
int a, b, c, d, e, f, g, h, i, j;
};
template <typename T>
struct make_abs_t
{
static void doit(const T& t)
{
if (t.head < 0) {
t.head = -t.head;
}
make_abs_t<typename T::tail_type>::doit(t.tail);
}
};
template <typename Car>
struct make_abs_t<boost::tuples::cons<Car, boost::tuples::null_type> >
{
static void doit(const boost::tuples::cons<Car, boost::tuples::null_type>& t)
{
if (t.head < 0) {
t.head = -t.head;
}
}
};
template <typename T>
inline void make_abs(const T& t)
{
make_abs_t<T>::doit(t);
}
void bar(foo& x)
{
make_abs(boost::tie(x.a, x.b, x.c, x.d, x.e, x.f, x.g, x.h, x.i, x.j));
}
void baz(foo& x)
{
if (x.a < 0) x.a = -x.a;
if (x.b < 0) x.b = -x.b;
if (x.c < 0) x.c = -x.c;
if (x.d < 0) x.d = -x.d;
if (x.e < 0) x.e = -x.e;
if (x.f < 0) x.f = -x.f;
if (x.g < 0) x.g = -x.g;
if (x.h < 0) x.h = -x.h;
if (x.i < 0) x.i = -x.i;
if (x.j < 0) x.j = -x.j;
}
template <typename T>
struct make_neg_t
{
static void doit(const T& t)
{
t.head = -t.head;
make_neg_t<typename T::tail_type>::doit(t.tail);
}
};
template <typename Car>
struct make_neg_t<boost::tuples::cons<Car, boost::tuples::null_type> >
{
static void doit(const boost::tuples::cons<Car, boost::tuples::null_type>& t)
{
t.head = -t.head;
}
};
template <typename T>
inline void make_neg(const T& t)
{
make_neg_t<T>::doit(t);
}
void bar_neg(foo& x)
{
make_neg(boost::tie(x.a, x.b, x.c, x.d, x.e, x.f, x.g, x.h, x.i, x.j));
}
void baz_neg(foo& x)
{
x.a = -x.a;
x.b = -x.b;
x.c = -x.c;
x.d = -x.d;
x.e = -x.e;
x.f = -x.f;
x.g = -x.g;
x.h = -x.h;
x.i = -x.i;
x.j = -x.j;
}