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