EGCS bad on loop invariant optimization ?

Gabriel Dos Reis Gabriel.Dos-Reis@dptmaths.ens-cachan.fr
Fri Apr 24 10:11:00 GMT 1998


>>>>> «Martin», Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de> wrote:


Martin> First I found this quite convincing. However, you'll have to keep the
Martin> C++ storage model in mind. In order to modify an object through a
Martin> pointer, you need to take the address of the object. In you second
Martin> example, g++ knows that the address of a, b, and c is never taken, so
Martin> it knows that no store operation might modify them (at least not in a
Martin> compliant program, non-compliant ones might exhibit unexpected
Martin> results).

Quite right.

Martin> So I modified your last test case to read

Martin> inline double& nth_element(double* data, unsigned i)
Martin> { return data[i]; }

Martin> inline double nth_element(const double* data, unsigned i)
Martin> { return data[i]; }


Martin> int main()
Martin> {
Martin>     const unsigned n = 1000;
Martin>     double* a = new double[n];
Martin>     double* b = new double[n];
Martin>     double* c = new double[n];

Martin>     extern void f(double **);
Martin>     f(&a);
Martin>     f(&b);
Martin>     f(&c);

Martin>     for (unsigned i=0; i<n; ++i)
Martin>         nth_element(a, i) = nth_element(static_cast<const double*>(b), i)
Martin>             + nth_element(static_cast<const double*>(c), i);

Martin>     return 0;
Martin> }

Martin> That way, g++ has no way of knowing what ::f does with the pointers
Martin> it gets. In turn, it generates for the loop:

Martin> .LL6:
Martin> 	cmp %o3,999
Martin> 	bgu .LL7
Martin> 	ld [%fp-24],%o1
Martin> 	ld [%fp-28],%o2
Martin> 	sll %o3,3,%o0
Martin> 	ldd [%o1+%o0],%f4
Martin> 	ldd [%o2+%o0],%f2
Martin> 	faddd %f4,%f2,%f4
Martin> 	ld [%fp-20],%o1
Martin> 	add %o3,1,%o3
Martin> 	b .LL6
Martin> 	std %f4,[%o1+%o0]

Martin> As you can see, it generates these superfluous (sp? sem?) loads. Now,
Martin> in C++, the address of almost every object is taken, as it is an
Martin> implicit parameter of non-static member functions. So in your first
Martin> case, it doesn't know that *this is a loop invariant for a,b, or c.

Yep. But, we (and g++ as well) know that the execution of f(&c); is
completed before entering the for-loop which doesn't included any
other function call whose sided effect is unknown. So my point is: in
the for-loop a, b, and c are loop invariants (because, function calls
involved are inlined, and the arguments aren't modified); how the
semantic could be affected if the loads of a, b, and c were moved out of
the loop ? 

What about this proposal: members functions declared *const*,
*inlined* (i.e. g++ does see their definitions) which are *leaf* 
functions should be subject to code-motion optimization ?


-- Gaby



More information about the Gcc mailing list