This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
analysis of gnats g++/720: abstraction penalty/inlining problems
- To: gcc at gcc dot gnu dot org
- Subject: analysis of gnats g++/720: abstraction penalty/inlining problems
- From: Joe Buck <jbuck at racerx dot synopsys dot com>
- Date: Fri, 3 Nov 2000 10:23:16 -0800 (PST)
I can duplicate the problem as shown in GNATS bug c++/720 with a far
simpler case, involving no templates or inline functions. Here it is:
-------------------------------------
double accumulate(double* first, double* last, double result)
{
while (first != last) {
const double& x = result;
const double& y = *first++;
double tmp = x + y;
result = tmp;
}
return result;
}
-------------------------------------
The while-loop body as generated by current snapshots has two loads and a
store (for sparc-sun-solaris, but I'm sure for other platforms as well),
while for 2.95.2 we get just a load.
The motivation for the above example is to approximate what the tree-based
inliner produces for
------------------------------------
inline double plus(const double& x, const double& y)
{
return x + y;
}
double accumulate(double* first, double* last, double result)
{
while (first != last)
result = plus(result, *first++);
return result;
}
------------------------------------
and I verified that the *exact* same code is produced for both of the
above two examples, except that a different register is chosen for
one of the variables.
Clearly ADDRESSOF has been broken, so that needs to be investigated. This
is a release-critical problem, because without addressing it we cannot
meet the requirement (from http://gcc.gnu.org/gcc-3.0/criteria.html ):
"A release candidate will be deemed unacceptable if the performance of the
generated code is not at least as good as that of GCC 2.95.2 on the
benchmarks [including Stepanov benchmark], and within at least 5% on the
application tests."
It seems that something like ADDRESSOF, only more effective (since it
would work for multi-element structs as well), could be done fairly
easily on the tree: do a pass that replaces uses of references with
uses of the object the references refers to, where this can be determined.
Because references are initialized when created and can't be changed,
this is vastly simpler than most dataflow problems.