[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: GNU attributes
From: |
Guus Leeuw jr. |
Subject: |
Re: GNU attributes |
Date: |
Tue, 25 Mar 2003 19:12:20 +0100 |
User-agent: |
KMail/1.5 |
On Tuesday 25 March 2003 18:17, Stefan Monnier <foo@acm.com> wrote:
> >>>>> "Derek" == Derek Robert Price <derek@ximbiot.com> writes:
> >
> > Anyone know whether a function that allocates memory can be considered
> > "pure", in the GNU attribute sense of the term?
>
> IIUC, the notion of a `pure' function is one whose return value
> is all the matters and is 100% determined by its arguments.
This is not true. It depends not only on arguments but on function internally
used global variables as well.
Example:
Iff f(x) = g(x) + 2 and g(x) = glob(a) + 5 and glob(a) changes from call to
call to f(x), saying f(x) is pure, will not trick the optimizer in calling
f(x) fewer times than the program says, since the result depends on a
changing global value!! f(x) will not deliver the same result for every call
with the same arguments!!
/* Assume int f(int) __attribute((__pure__)); */
glob(a) = 1;
r1 = f(5);
glob(a) = 2;
r2 = f(5);
if(r1 == r2)
printf("Bugger Off, Duh...\n");
else
printf("Sounds right...\n");
> I.e. a call to such a function can be removed if the result is not used
> and two calls can be CSE'd if the args are the same.
Whether the result is used does not make a difference. First of all, if the
result is only read, the optimizer is safe to compute it once.
Second, if the function result is changed, the optimizer might be smart enough
to store the result on the stack (This is not defined in the GCC manual, so
I don't know whether they do it or not.)
To extend the example from above:
r3 = f(5);
if(r2 == r3)
printf("It works\n");
else
printf("no it don't");
the statement r3 = f(5) *might* be optimized away and replaced by r3 = r2;
Then the if expression might be replaced by "if(r2 == r2)" and hence the whole
example could be replaced by a mere printf("It works\n");
This holds even iff f(5) were to return a malloc()ed block of memory.
Just make sure you free(r1); and free(r2); but *not* r3 (since it *should* be
a copy of r2 #ifdef __GNU)
<strong><advise>Test it on EFence, though, Derek.</advise></strong>
And then there is the question about when does the optimizer look at this?
-O1? -O3? who knows?
Ah ja... Just making matters worse I guess... Thank God I'm of help *harhar*
Better ask the GNU optimizer guy(s) on this one :) ...
... Or look at the internal documentation of gcc.
:%s/internal documentation/code/
Cheers,
Guus