public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Optimizing of explicit temporary storage
@ 2004-10-10 21:51 Richard Guenther
  2004-10-11  4:34 ` Mike Stump
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Guenther @ 2004-10-10 21:51 UTC (permalink / raw)
  To: gcc

Is it legal for a conforming C++ compiler to optimize away storage 
allocation / deallocation?  Like in

#include <new>

void foo(void)
{
         int *x = new(std::nothrow) int;
         delete x;
}

is it allowed to kill the new and delete statements?  Would it be 
allowed to do this for the throwing version of new, too?

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-10 21:51 Optimizing of explicit temporary storage Richard Guenther
@ 2004-10-11  4:34 ` Mike Stump
  2004-10-11  7:11   ` Richard Guenther
  0 siblings, 1 reply; 22+ messages in thread
From: Mike Stump @ 2004-10-11  4:34 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc

On Sunday, October 10, 2004, at 07:48  AM, Richard Guenther wrote:
> Is it legal for a conforming C++ compiler to optimize away storage 
> allocation / deallocation?  Like in
>
> #include <new>
>
> void foo(void)
> {
>         int *x = new(std::nothrow) int;
>         delete x;
> }
>
> is it allowed to kill the new and delete statements?  Would it be 
> allowed to do this for the throwing version of new, too?

The as if rule is fairly powerful...  If the resulting program behaves 
as if it had it, then the optimization is allowed.  I don't think 
memory consumption is an externally visible effect.  Now, we might need 
to do full program analysis to know which new is run, and to know its 
semantics; I don't recall if the user is prohibited from adding 
semantics to a new replacement function.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-11  4:34 ` Mike Stump
@ 2004-10-11  7:11   ` Richard Guenther
  2004-10-12  7:38     ` Mark Mitchell
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Guenther @ 2004-10-11  7:11 UTC (permalink / raw)
  To: Mike Stump; +Cc: gcc

Mike Stump wrote:
> On Sunday, October 10, 2004, at 07:48  AM, Richard Guenther wrote:
> 
>> Is it legal for a conforming C++ compiler to optimize away storage 
>> allocation / deallocation?  Like in
>>
>> #include <new>
>>
>> void foo(void)
>> {
>>         int *x = new(std::nothrow) int;
>>         delete x;
>> }
>>
>> is it allowed to kill the new and delete statements?  Would it be 
>> allowed to do this for the throwing version of new, too?
> 
> The as if rule is fairly powerful...  If the resulting program behaves 
> as if it had it, then the optimization is allowed.  I don't think memory 
> consumption is an externally visible effect.  Now, we might need to do 
> full program analysis to know which new is run, and to know its 
> semantics; I don't recall if the user is prohibited from adding 
> semantics to a new replacement function.

Well, I was thinking of the traditional

struct Vector {
    Vector(int size);
    Vector operator*(const Vector&);
    Vector& operator=(const Vector&);
    double *storage;
};

and doing expressions like

Vector a,b,c;
a = b*c;

where one usually considers using expression templates because of the 
temporaries.  With loop fusion one could get the speed of the expression 
template code, but are you allowed to get rid of the temporaries (and 
their allocated memory), too?

Richard.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-11  7:11   ` Richard Guenther
@ 2004-10-12  7:38     ` Mark Mitchell
  2004-10-12  8:40       ` Florian Weimer
  2004-10-12  9:02       ` Kai Henningsen
  0 siblings, 2 replies; 22+ messages in thread
From: Mark Mitchell @ 2004-10-12  7:38 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Mike Stump, gcc

Richard Guenther wrote:

> Mike Stump wrote:
>
>> On Sunday, October 10, 2004, at 07:48  AM, Richard Guenther wrote:
>>
>>> Is it legal for a conforming C++ compiler to optimize away storage 
>>> allocation / deallocation?  Like in
>>>
>>> #include <new>
>>>
>>> void foo(void)
>>> {
>>>         int *x = new(std::nothrow) int;
>>>         delete x;
>>> }
>>>
>>> is it allowed to kill the new and delete statements?  Would it be 
>>> allowed to do this for the throwing version of new, too?
>>
>>
>> The as if rule is fairly powerful...  If the resulting program 
>> behaves as if it had it, then the optimization is allowed.  I don't 
>> think memory consumption is an externally visible effect.  Now, we 
>> might need to do full program analysis to know which new is run, and 
>> to know its semantics; I don't recall if the user is prohibited from 
>> adding semantics to a new replacement function.
>
>
> Well, I was thinking of the traditional
>
> struct Vector {
>    Vector(int size);
>    Vector operator*(const Vector&);
>    Vector& operator=(const Vector&);
>    double *storage;
> };
>
> and doing expressions like
>
> Vector a,b,c;
> a = b*c;
>
> where one usually considers using expression templates because of the 
> temporaries.  With loop fusion one could get the speed of the 
> expression template code, but are you allowed to get rid of the 
> temporaries (and their allocated memory), too?

As Mike says, if you can prove that there are no side-effects, then, 
yes, you can.  But, that's in general impossible; even with 
whole-program analysis, you see that "::operator new" calls 
"std::malloc" and "std::malloc" eventually makes a syscall.  I don't 
think any compiler has ever attempted to turn:

  free (malloc (16));

into a no-op, which would be a simpler case.

So, I think that for practical purposes, you're not going to find that 
compilers get rid of these kinds of calls.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  7:38     ` Mark Mitchell
@ 2004-10-12  8:40       ` Florian Weimer
  2004-10-12  9:37         ` Mark Mitchell
  2004-10-12  9:02       ` Kai Henningsen
  1 sibling, 1 reply; 22+ messages in thread
From: Florian Weimer @ 2004-10-12  8:40 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: gcc

* Mark Mitchell:

> I don't think any compiler has ever attempted to turn:
>
>  free (malloc (16));
>
> into a no-op, which would be a simpler case.

There are scheme compilers that turn heap allocation into stack
allocation if they can prove that the object does not escape.
Java code would benefit from this optimization, too.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  7:38     ` Mark Mitchell
  2004-10-12  8:40       ` Florian Weimer
@ 2004-10-12  9:02       ` Kai Henningsen
  2004-10-12 19:36         ` Mike Stump
  1 sibling, 1 reply; 22+ messages in thread
From: Kai Henningsen @ 2004-10-12  9:02 UTC (permalink / raw)
  To: gcc

mark@codesourcery.com (Mark Mitchell)  wrote on 11.10.04 in <416B47AA.3010106@codesourcery.com>:

> Richard Guenther wrote:
>
> > Mike Stump wrote:
> >
> >> On Sunday, October 10, 2004, at 07:48  AM, Richard Guenther wrote:
> >>
> >>> Is it legal for a conforming C++ compiler to optimize away storage
> >>> allocation / deallocation?  Like in
> >>>
> >>> #include <new>
> >>>
> >>> void foo(void)
> >>> {
> >>>         int *x = new(std::nothrow) int;
> >>>         delete x;
> >>> }
> >>>
> >>> is it allowed to kill the new and delete statements?  Would it be
> >>> allowed to do this for the throwing version of new, too?
> >>
> >>
> >> The as if rule is fairly powerful...  If the resulting program
> >> behaves as if it had it, then the optimization is allowed.  I don't
> >> think memory consumption is an externally visible effect.  Now, we
> >> might need to do full program analysis to know which new is run, and
> >> to know its semantics; I don't recall if the user is prohibited from
> >> adding semantics to a new replacement function.
> >
> >
> > Well, I was thinking of the traditional
> >
> > struct Vector {
> >    Vector(int size);
> >    Vector operator*(const Vector&);
> >    Vector& operator=(const Vector&);
> >    double *storage;
> > };
> >
> > and doing expressions like
> >
> > Vector a,b,c;
> > a = b*c;
> >
> > where one usually considers using expression templates because of the
> > temporaries.  With loop fusion one could get the speed of the
> > expression template code, but are you allowed to get rid of the
> > temporaries (and their allocated memory), too?
>
> As Mike says, if you can prove that there are no side-effects, then,
> yes, you can.  But, that's in general impossible; even with
> whole-program analysis, you see that "::operator new" calls
> "std::malloc" and "std::malloc" eventually makes a syscall.  I don't
> think any compiler has ever attempted to turn:
>
>   free (malloc (16));
>
> into a no-op, which would be a simpler case.

Any of these cases can, it seems to me, not really be handled well with  
any kind of whole-program analysis.

Instead, what you'd need is to use some sort of language guarantees about  
the behaviour of the allocation functions themselves (new, delete, malloc,  
free) so the decision becomes local.

This is not really different from optimizing, say, the strXXX() functions.  
You don't look at how they are implemented, you look at what the standard  
tells you about what they do.

Assume you had a strange OS where strlen() was a syscall. You could still  
optimize strlen("foo") to 3, as long as you do *not* try to look at how it  
is actually implemented.

MfG Kai

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  8:40       ` Florian Weimer
@ 2004-10-12  9:37         ` Mark Mitchell
  2004-10-12 11:59           ` Robert Dewar
                             ` (3 more replies)
  0 siblings, 4 replies; 22+ messages in thread
From: Mark Mitchell @ 2004-10-12  9:37 UTC (permalink / raw)
  To: Florian Weimer; +Cc: gcc

Florian Weimer wrote:

>* Mark Mitchell:
>
>  
>
>>I don't think any compiler has ever attempted to turn:
>>
>> free (malloc (16));
>>
>>into a no-op, which would be a simpler case.
>>    
>>
>
>There are scheme compilers that turn heap allocation into stack
>allocation if they can prove that the object does not escape.
>Java code would benefit from this optimization, too.
>  
>
Yes, but that's rather a different situation due to the nature of Scheme.

In C, even given just:

  (void) malloc(16);

it would be surprising to most programmers to optimize away the call 
because malloc *does* have side-effects on real systems.  For example, 
on UNIX, it is likely to call sbrk, which result in observable changes 
in the process state.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  9:37         ` Mark Mitchell
@ 2004-10-12 11:59           ` Robert Dewar
  2004-10-12 12:19             ` Mark Mitchell
  2004-10-12 19:44           ` Mike Stump
                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 22+ messages in thread
From: Robert Dewar @ 2004-10-12 11:59 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Florian Weimer, gcc

Mark Mitchell wrote:

> In C, even given just:
> 
>  (void) malloc(16);
> 
> it would be surprising to most programmers to optimize away the call 
> because malloc *does* have side-effects on real systems.  For example, 
> on UNIX, it is likely to call sbrk, which result in observable changes 
> in the process state.

Yes, but the condition of not surprising programmers is different from
the condition of conforming to the standard. Strictly from a standards
conformance point of view, these kinds of optimization seem perfectly
valid, but of course the criterion of not surprising programmers is
indeed a reasonable one!

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12 11:59           ` Robert Dewar
@ 2004-10-12 12:19             ` Mark Mitchell
  2004-10-12 13:10               ` Robert Dewar
  0 siblings, 1 reply; 22+ messages in thread
From: Mark Mitchell @ 2004-10-12 12:19 UTC (permalink / raw)
  To: Robert Dewar; +Cc: Florian Weimer, gcc

Robert Dewar wrote:

> Mark Mitchell wrote:
>
>> In C, even given just:
>>
>>  (void) malloc(16);
>>
>> it would be surprising to most programmers to optimize away the call 
>> because malloc *does* have side-effects on real systems.  For 
>> example, on UNIX, it is likely to call sbrk, which result in 
>> observable changes in the process state.
>
>
> Yes, but the condition of not surprising programmers is different from
> the condition of conforming to the standard. Strictly from a standards
> conformance point of view, these kinds of optimization seem perfectly
> valid, but of course the criterion of not surprising programmers is
> indeed a reasonable one!

I'm not sure stanadards are all that relevant here, since most real C 
programs go beyond the set of library functions standardized by ISO, or 
even POSIX.

The as-if rule says that the compiler can perform the optimization only 
if the program can't tell the difference.  I don't think it means "can't 
tell the difference using functions from the ISO C standard library;" 
instead, I think it means "can't tell the difference in the current 
environment."  Certainly, calling malloc has observable side effects on 
most UNIX systems; I can see whether or not processes are calling malloc 
by running "top".

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12 12:19             ` Mark Mitchell
@ 2004-10-12 13:10               ` Robert Dewar
  0 siblings, 0 replies; 22+ messages in thread
From: Robert Dewar @ 2004-10-12 13:10 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Florian Weimer, gcc

Mark Mitchell wrote:

> The as-if rule says that the compiler can perform the optimization only 
> if the program can't tell the difference.  I don't think it means "can't 
> tell the difference using functions from the ISO C standard library;" 
> instead, I think it means "can't tell the difference in the current 
> environment."  Certainly, calling malloc has observable side effects on 
> most UNIX systems; I can see whether or not processes are calling malloc 
> by running "top".

Anything has observable effects in this respect, because it changes the
code generated, which changes the cache usage, size of external object
files etc etc. Indeed it is perfectly easy to observe all kinds of things
using tools like gdb, objdump etc.

When we are talking about standards conformance, we restrict our attention
strictly to the standard, and what we mean by the as-if rule is that we
cannot write a C program whose meaning is defined by the standard that
can tell the difference at the semantic level of description in the
standard.

That is why you often have to go beyond the standard in deciding when
it is appropriate to do transformations that may violate programmer
expectations, even if these expectations are not derivable from the
standard.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  9:02       ` Kai Henningsen
@ 2004-10-12 19:36         ` Mike Stump
  0 siblings, 0 replies; 22+ messages in thread
From: Mike Stump @ 2004-10-12 19:36 UTC (permalink / raw)
  To: Kai Henningsen; +Cc: gcc

On Oct 11, 2004, at 11:44 PM, Kai Henningsen wrote:
> Instead, what you'd need is to use some sort of language guarantees 
> about  
> the behaviour of the allocation functions themselves (new, delete, 
> malloc,  
> free) so the decision becomes local.

Or a simple statement in the language definition that pairs can be 
optimized away in the right situation, even if there are side 
effects...  For example, a user defined new/delete that does a printf 
could be considered ok, and that the compiler can get rid of pairs 
output lines.

Making this a local decision would be a good language direction for C++.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  9:37         ` Mark Mitchell
  2004-10-12 11:59           ` Robert Dewar
@ 2004-10-12 19:44           ` Mike Stump
  2004-10-13  2:27           ` Geoffrey Keating
  2004-10-13 11:45           ` Nick Ing-Simmons
  3 siblings, 0 replies; 22+ messages in thread
From: Mike Stump @ 2004-10-12 19:44 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Florian Weimer, gcc

On Oct 12, 2004, at 12:00 AM, Mark Mitchell wrote:
> In C, even given just:
>
>  (void) malloc(16);
>
> it would be surprising to most programmers to optimize away the call 
> because malloc *does* have side-effects on real systems.  For example, 
> on UNIX, it is likely to call sbrk, which result in observable changes 
> in the process state.

There are details (side-effects as you call them) that can be observed 
with gdb, that are not to be interpreted having any relationship with 
the term side-effect or observable behavior in the language standard; 
by this I mean are to be allowed by the optimizer.  In the more general 
standard of a real system, we have to decide which details are 
important (side-effects or observable behaviors) and which aren't, 
that's our job.  As we do higher level optimizations, we have to 
consider exactly which details we want to be side-effects, and which we 
don't want to be, and why.  We can debate just how much information is 
to be required for a particular optimization, that's part of the 
language design.  I'd argue that exactly when sbrk is called under 
malloc isn't an observable side-effect, even on a UNIX system.  I'd 
argue that the value of malloc, likewise, isn't important.

For some languages, this type of optimization is going to be more 
beneficial than for other languages, for C is might not make any 
sense.  For objc or java, I think it might make more sense.  For C, we 
might want to define our language as not permitting it, but for objc, 
to allow it.

Anyway, we can postpone further discussions on this topic until such 
time as someone seriously wants to consider adding it...

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  9:37         ` Mark Mitchell
  2004-10-12 11:59           ` Robert Dewar
  2004-10-12 19:44           ` Mike Stump
@ 2004-10-13  2:27           ` Geoffrey Keating
  2004-10-13  3:42             ` Daniel Berlin
  2004-10-13 11:45           ` Nick Ing-Simmons
  3 siblings, 1 reply; 22+ messages in thread
From: Geoffrey Keating @ 2004-10-13  2:27 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: gcc

Mark Mitchell <mark@codesourcery.com> writes:

> Florian Weimer wrote:
> 
> >* Mark Mitchell:
> >
> >
> >>I don't think any compiler has ever attempted to turn:
> >>
> >> free (malloc (16));
> >>
> >>into a no-op, which would be a simpler case.
> >>
> >
> >There are scheme compilers that turn heap allocation into stack
> >allocation if they can prove that the object does not escape.
> >Java code would benefit from this optimization, too.
> >
> Yes, but that's rather a different situation due to the nature of Scheme.
> 
> In C, even given just:
> 
>   (void) malloc(16);
> 
> it would be surprising to most programmers to optimize away the call
> because malloc *does* have side-effects on real systems.  For example,
> on UNIX, it is likely to call sbrk, which result in observable changes
> in the process state.

Well, yes, but

        int x[65536];

also results in observable changes in the process state, and we don't
hesitate to optimise it away.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13  2:27           ` Geoffrey Keating
@ 2004-10-13  3:42             ` Daniel Berlin
  2004-10-13  9:18               ` Chris Lattner
  0 siblings, 1 reply; 22+ messages in thread
From: Daniel Berlin @ 2004-10-13  3:42 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: Mark Mitchell, gcc, sabre

>>>
>> Yes, but that's rather a different situation due to the nature of Scheme.
>>
>> In C, even given just:
>>
>>   (void) malloc(16);
>>
>> it would be surprising to most programmers to optimize away the call
>> because malloc *does* have side-effects on real systems.  For example,
>> on UNIX, it is likely to call sbrk, which result in observable changes
>> in the process state.
>
> Well, yes, but
>
>        int x[65536];
>
> also results in observable changes in the process state, and we don't
> hesitate to optimise it away.

I believe LLVM actually does all kinds of promotion that ends up removing 
malloc calls.   Maybe i'm just misremembering.
Chris, am i on crack?

--Dan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13  3:42             ` Daniel Berlin
@ 2004-10-13  9:18               ` Chris Lattner
  2004-10-13 10:47                 ` Kai Henningsen
  2004-10-13 13:22                 ` Daniel Berlin
  0 siblings, 2 replies; 22+ messages in thread
From: Chris Lattner @ 2004-10-13  9:18 UTC (permalink / raw)
  To: Daniel Berlin; +Cc: Geoffrey Keating, Mark Mitchell, gcc

On Tue, 12 Oct 2004, Daniel Berlin wrote:

> >> Yes, but that's rather a different situation due to the nature of Scheme.
> >>
> >> In C, even given just:
> >>
> >>   (void) malloc(16);
> >>
> >> it would be surprising to most programmers to optimize away the call
> >> because malloc *does* have side-effects on real systems.  For example,
> >> on UNIX, it is likely to call sbrk, which result in observable changes
> >> in the process state.
> >
> > Well, yes, but
> >
> >        int x[65536];
> >
> > also results in observable changes in the process state, and we don't
> > hesitate to optimise it away.
>
> I believe LLVM actually does all kinds of promotion that ends up removing
> malloc calls.   Maybe i'm just misremembering.

Yes, LLVM deletes dead malloc calls and does other things as well.  The C
spec defines the behavior of malloc/free, and from this description I
believe that it is safe to do this (e.g. C99 second 7.20.3).  Note,
however, that Mark's point above about calling sbrk is beyond the
standard: conformant programs can't know anything about sbrk.

Assuming standards compliant programs, this can still cause changes in
observable behavior.  In particular, something like this:

malloc(HEAPSIZE-100);   // dead
P = malloc(1000);       // not dead
*P = x;

Would cause *P to trap for a suitable value of HEAPSIZE (the second malloc
would return null) in an unmodified program.  In the optimized program the
second call would not return zero.   However again, portable program's
can't really know the size of the heap (malloc can fail at any time (e.g.
due to fragmentation issues) so the program can't even portably probe) so
this is not an issue.

If we are talking about being a C compiler, I think that's as far as it
goes.  However, almost no programs *only* use features from the standard,
so as a QOI feature, adding an argument to disable this kind of thing
might be useful: -fno-builtins seems reasonable to me.  Note that most
programmers would be very happy to have their memory usage optimized, so
IMHO it should be the default.  Obviously you guys have to choose what you
think is right for GCC.

Also note that the comments above only apply to malloc/free.  We don't do
anything special with operator new/delete, though in the future we might
at link-time (we need to detect that a version with known behavior is
linked to, that a new_handler has not been installed, and potentially
other things).

To me, I consider it a defect in the language that the C++ std (as far as
I can tell) does not explicitly allow optimization of operator new/delete,
just like we can optimize out copy ctors.  In particular, the restrictions
placed on allocation functions (3.7.3.1 in C++2003) specify restrictions
that callers must obey, but does not say anything about side effects or
optimizability or restrictions that implementations and new_handlers must
respect.

> Chris, am i on crack?

I don't know Dan, it's hard for me to say, are you?  :-)

-Chris

-- 
http://llvm.org/
http://nondot.org/sabre/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13  9:18               ` Chris Lattner
@ 2004-10-13 10:47                 ` Kai Henningsen
  2004-10-13 13:22                 ` Daniel Berlin
  1 sibling, 0 replies; 22+ messages in thread
From: Kai Henningsen @ 2004-10-13 10:47 UTC (permalink / raw)
  To: gcc

sabre@nondot.org (Chris Lattner)  wrote on 12.10.04 in <Pine.LNX.4.44.0410122302530.31127-100000@nondot.org>:

> On Tue, 12 Oct 2004, Daniel Berlin wrote:
>
> > >> Yes, but that's rather a different situation due to the nature of
> > >> Scheme.
> > >>
> > >> In C, even given just:
> > >>
> > >>   (void) malloc(16);
> > >>
> > >> it would be surprising to most programmers to optimize away the call
> > >> because malloc *does* have side-effects on real systems.  For example,
> > >> on UNIX, it is likely to call sbrk, which result in observable changes
> > >> in the process state.
> > >
> > > Well, yes, but
> > >
> > >        int x[65536];
> > >
> > > also results in observable changes in the process state, and we don't
> > > hesitate to optimise it away.
> >
> > I believe LLVM actually does all kinds of promotion that ends up removing
> > malloc calls.   Maybe i'm just misremembering.
>
> Yes, LLVM deletes dead malloc calls and does other things as well.  The C
> spec defines the behavior of malloc/free, and from this description I
> believe that it is safe to do this (e.g. C99 second 7.20.3).  Note,
> however, that Mark's point above about calling sbrk is beyond the
> standard: conformant programs can't know anything about sbrk.

Especially as that is strictly an internal library design decision: there  
are certainly implementations that, say, use mmap() instead, and leave  
sbrk() alone.

MfG Kai

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-12  9:37         ` Mark Mitchell
                             ` (2 preceding siblings ...)
  2004-10-13  2:27           ` Geoffrey Keating
@ 2004-10-13 11:45           ` Nick Ing-Simmons
  2004-10-13 13:02             ` Giovanni Bajo
  2004-10-14  4:21             ` Mike Stump
  3 siblings, 2 replies; 22+ messages in thread
From: Nick Ing-Simmons @ 2004-10-13 11:45 UTC (permalink / raw)
  To: mark; +Cc: gcc, Florian Weimer

Mark Mitchell <mark@codesourcery.com> writes:
>>
>Yes, but that's rather a different situation due to the nature of Scheme.
>
>In C, even given just:
>
>  (void) malloc(16);
>
>it would be surprising to most programmers to optimize away the call 
>because malloc *does* have side-effects on real systems.  For example, 
>on UNIX, it is likely to call sbrk, which result in observable changes 
>in the process state.

Indeed! - I have actually written 

free(malloc(estimated_total_need));

To get expensive sbrk() call out of the way with one big one
rather than many smaller ones.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13 11:45           ` Nick Ing-Simmons
@ 2004-10-13 13:02             ` Giovanni Bajo
  2004-10-13 13:12               ` Nick Ing-Simmons
  2004-10-14  4:21             ` Mike Stump
  1 sibling, 1 reply; 22+ messages in thread
From: Giovanni Bajo @ 2004-10-13 13:02 UTC (permalink / raw)
  To: Nick Ing-Simmons; +Cc: gcc

Nick Ing-Simmons wrote:

>> it would be surprising to most programmers to optimize away the call
>> because malloc *does* have side-effects on real systems.  For
>> example, on UNIX, it is likely to call sbrk, which result in
>> observable changes in the process state.
> 
> Indeed! - I have actually written
> 
> free(malloc(estimated_total_need));
> 
> To get expensive sbrk() call out of the way with one big one
> rather than many smaller ones.

So why not calling sbrk() directly?

Giovanni Bajo


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13 13:02             ` Giovanni Bajo
@ 2004-10-13 13:12               ` Nick Ing-Simmons
  0 siblings, 0 replies; 22+ messages in thread
From: Nick Ing-Simmons @ 2004-10-13 13:12 UTC (permalink / raw)
  To: giovannibajo; +Cc: gcc, Nick Ing-Simmons

Giovanni Bajo <giovannibajo@libero.it> writes:
>Nick Ing-Simmons wrote:
>
>>> it would be surprising to most programmers to optimize away the call
>>> because malloc *does* have side-effects on real systems.  For
>>> example, on UNIX, it is likely to call sbrk, which result in
>>> observable changes in the process state.
>> 
>> Indeed! - I have actually written
>> 
>> free(malloc(estimated_total_need));
>> 
>> To get expensive sbrk() call out of the way with one big one
>> rather than many smaller ones.
>
>So why not calling sbrk() directly?

Getting off-topic but:

Because calling sbrk() gives me once one big chunk of memory
not lots of little ones. So I would still have to "chip off" bits 
for each "object". 

In my case the malloc()s were in a library which was not to be 
re-coded, and were intermixed with free()s so simplistic slab 
allocator replacement didn't work well.

Emprically (on the Solaris 2.6 machine I was using at the time)
adding this:

  free(malloc(100000*sizeof(Foo));

Before code that had similar effect to:

  for (i=0; i < 100000; i++)
   {
    p = (Foo *) malloc(sizeof(Foo));  // really a library call as result of parse
   }

made it faster. Without the free(malloc()) it made a syscall 
to do the sbrk() for every "page or so" worth of heap it wanted.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13  9:18               ` Chris Lattner
  2004-10-13 10:47                 ` Kai Henningsen
@ 2004-10-13 13:22                 ` Daniel Berlin
  2004-10-13 16:06                   ` Chris Lattner
  1 sibling, 1 reply; 22+ messages in thread
From: Daniel Berlin @ 2004-10-13 13:22 UTC (permalink / raw)
  To: Chris Lattner; +Cc: Geoffrey Keating, Mark Mitchell, gcc

>>
>> I believe LLVM actually does all kinds of promotion that ends up removing
>> malloc calls.   Maybe i'm just misremembering.
>
> Yes, LLVM deletes dead malloc calls and does other things as well.  The C
> spec defines the behavior of malloc/free, and from this description I
> believe that it is safe to do this (e.g. C99 second 7.20.3).  Note,
> however, that Mark's point above about calling sbrk is beyond the
> standard: conformant programs can't know anything about sbrk.
>
> Assuming standards compliant programs, this can still cause changes in
> observable behavior.  In particular, something like this:
>
> malloc(HEAPSIZE-100);   // dead
> P = malloc(1000);       // not dead
> *P = x;

>> Chris, am i on crack?
>
> I don't know Dan, it's hard for me to say, are you?  :-)

:)

Also, isn't your thesis on automatic conversion of programs to use pool 
allocation?

Won't that change malloc->pool_alloc?

Or is this something you didn't plan on making the default in LLVM?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13 13:22                 ` Daniel Berlin
@ 2004-10-13 16:06                   ` Chris Lattner
  0 siblings, 0 replies; 22+ messages in thread
From: Chris Lattner @ 2004-10-13 16:06 UTC (permalink / raw)
  To: Daniel Berlin; +Cc: Geoffrey Keating, Mark Mitchell, gcc

On Wed, 13 Oct 2004, Daniel Berlin wrote:

> > Yes, LLVM deletes dead malloc calls and does other things as well.  The C
> > spec defines the behavior of malloc/free, and from this description I
> > believe that it is safe to do this (e.g. C99 second 7.20.3).  Note,
> > however, that Mark's point above about calling sbrk is beyond the
> > standard: conformant programs can't know anything about sbrk.
> >
> > Assuming standards compliant programs, this can still cause changes in
> > observable behavior.  In particular, something like this:
> >
> > malloc(HEAPSIZE-100);   // dead
> > P = malloc(1000);       // not dead
> > *P = x;
>
> >> Chris, am i on crack?
> >
> > I don't know Dan, it's hard for me to say, are you?  :-)
>
> :)
>
> Also, isn't your thesis on automatic conversion of programs to use pool
> allocation?
>
> Won't that change malloc->pool_alloc?

Yes, that's the first chunk of my thesis work, and falls into the "other
stuff as well" catagory.  :)  Note, however, that the generated code is
substantially different than the libstdc++ style of pools.  From my
understanding, libstdc++'s pool allocator is basically a malloc
replacement by now that allows multiple heaps.  The code generated by my
pool allocation xform ends up using short lived pools as much as possible,
perhaps most similar in spirit to the GCC zone collector.  For example, if
you have two std::sets with elements of the same types, the LLVM pool
allocator would put the nodes into different pools.

> Or is this something you didn't plan on making the default in LLVM?

It's not something that will be default for a long time (perhaps ever?).
First of all it's not robust enough or predictable enough yet.  Second, I
think that automatic pool allocation is an aggressive enough
transformation that it should be enabled explicitly by the user.  OTOH,
the underlying heap analysis may become the default AA in the future,
we'll just have to see.  Currently LLVM uses a pretty trivial alias
analysis by default.

-Chris

-- 
http://llvm.org/
http://nondot.org/sabre/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Optimizing of explicit temporary storage
  2004-10-13 11:45           ` Nick Ing-Simmons
  2004-10-13 13:02             ` Giovanni Bajo
@ 2004-10-14  4:21             ` Mike Stump
  1 sibling, 0 replies; 22+ messages in thread
From: Mike Stump @ 2004-10-14  4:21 UTC (permalink / raw)
  To: Nick Ing-Simmons; +Cc: mark, gcc, Florian Weimer

On Oct 13, 2004, at 2:19 AM, Nick Ing-Simmons wrote:
> Indeed! - I have actually written 
>
> free(malloc(estimated_total_need));
>
> To get expensive sbrk() call out of the way with one big one
> rather than many smaller ones.

This code might already be broken the the malloc optimization that uses 
mmap for larger regions, and unmaps the large regions on free.  :-)

But, this is exactly the type of thing people can think about...   very 
relevant and obscure.

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2004-10-13 23:57 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-10 21:51 Optimizing of explicit temporary storage Richard Guenther
2004-10-11  4:34 ` Mike Stump
2004-10-11  7:11   ` Richard Guenther
2004-10-12  7:38     ` Mark Mitchell
2004-10-12  8:40       ` Florian Weimer
2004-10-12  9:37         ` Mark Mitchell
2004-10-12 11:59           ` Robert Dewar
2004-10-12 12:19             ` Mark Mitchell
2004-10-12 13:10               ` Robert Dewar
2004-10-12 19:44           ` Mike Stump
2004-10-13  2:27           ` Geoffrey Keating
2004-10-13  3:42             ` Daniel Berlin
2004-10-13  9:18               ` Chris Lattner
2004-10-13 10:47                 ` Kai Henningsen
2004-10-13 13:22                 ` Daniel Berlin
2004-10-13 16:06                   ` Chris Lattner
2004-10-13 11:45           ` Nick Ing-Simmons
2004-10-13 13:02             ` Giovanni Bajo
2004-10-13 13:12               ` Nick Ing-Simmons
2004-10-14  4:21             ` Mike Stump
2004-10-12  9:02       ` Kai Henningsen
2004-10-12 19:36         ` Mike Stump

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).