EGCS bad on loop invariant optimization ?
Martin von Loewis
martin@mira.isdn.cs.tu-berlin.de
Thu Apr 23 06:57:00 GMT 1998
> Hmm. I can't get the point. Let me show my ignorance. Consider the
> following code:
[snip]
> As you can see, there is no store/load of a, b and c inside the loop.
First I found this quite convincing. However, you'll have to keep the
C++ storage model in mind. In order to modify an object through a
pointer, you need to take the address of the object. In you second
example, g++ knows that the address of a, b, and c is never taken, so
it knows that no store operation might modify them (at least not in a
compliant program, non-compliant ones might exhibit unexpected
results).
So I modified your last test case to read
inline double& nth_element(double* data, unsigned i)
{ return data[i]; }
inline double nth_element(const double* data, unsigned i)
{ return data[i]; }
int main()
{
const unsigned n = 1000;
double* a = new double[n];
double* b = new double[n];
double* c = new double[n];
extern void f(double **);
f(&a);
f(&b);
f(&c);
for (unsigned i=0; i<n; ++i)
nth_element(a, i) = nth_element(static_cast<const double*>(b), i)
+ nth_element(static_cast<const double*>(c), i);
return 0;
}
That way, g++ has no way of knowing what ::f does with the pointers
it gets. In turn, it generates for the loop:
.LL6:
cmp %o3,999
bgu .LL7
ld [%fp-24],%o1
ld [%fp-28],%o2
sll %o3,3,%o0
ldd [%o1+%o0],%f4
ldd [%o2+%o0],%f2
faddd %f4,%f2,%f4
ld [%fp-20],%o1
add %o3,1,%o3
b .LL6
std %f4,[%o1+%o0]
As you can see, it generates these superfluous (sp? sem?) loads. Now,
in C++, the address of almost every object is taken, as it is an
implicit parameter of non-static member functions. So in your first
case, it doesn't know that *this is a loop invariant for a,b, or c.
Regards,
Martin
More information about the Gcc
mailing list