[LLVMdev] optimization assumes malloc return is non-null

Mike Stump mrs at apple.com
Thu May 1 15:11:33 PDT 2008


On Apr 30, 2008, at 9:26 PM, Chris Lattner wrote:
> Personally to me, I have a bigger axe to grind with C++ operator new.
> AFAIK, the standard doesn't give leeway to do a number of interesting
> optimizations for new/delete because the user is explicitly allowed to
> override them and the std doesn't require them to behave "as
> expected".

Yes it does:

   Replaceable:
     a  C++  program  may  define a function with this function  
signature
     that displaces the default  version  defined  by  the  C++   
Standard
     library.
   Required behavior:
     Return    a   non-null   pointer   to   suitably   aligned    
storage
     (_basic.stc.dynamic_), or else throw a  bad_alloc  exception.    
This
     requirement is binding on a replacement version of this function.

These _are_ the defined semantics.  You cannot imagine any other  
semantic and substitute it.  Any program that does, is outside the  
scope of the standard and has _no_ constraint upon it.  Meaning, the  
compiler free to do anything, technically.

The latitude exists to do exactly what you want to do as in  
intelligent optimization person.

You can see that this is what the standard mandates by imagining what  
would happen if you had the allocator return the same pointer to the  
same memory all the time that was maximally aligned.  What does cout  
<< "Hi" << "there" do, or some other complex program that underneath  
wanted to use the allocator?  Either, they _have_ to work, which is  
impossible and nonsensical, or there has to be enough latitude in the  
standard to allow the code to not work.  The requirements on the  
replacement versions of the allocators is the constraint that provides  
the mechanism to decide wether your program is going to work.  If you  
behaves exactly as if you allocated suitably aligned storage and  
return it or throw bad_alloc, then, the execution of the program is as  
constrained by the abstract semantics.  If not then _all_ requirements  
of the standard are vacated.  In particular, printf("Hi") in the  
allocator means the standard places no requirements on the program.   
You can print Hi, not print it, print it twice, whatever you want.

>  Very interesting properties to me would be:
>
> 1) Safety to remove "delete (new int);" and friends.

You are free to do that.

> 2) Aliasing guarantees about the result of new.

The replacements have their behavior required (you can also read this  
as constrained).  They are required to allocate new memory, and  
aliasing falls out from that.

> There are a huge number of code pessimizations that happen because  
> the optimizer has to
> assume that 'new' can return a pointer that already exists in the
> program.

This one is safe.  It has to behaves as if it allocates storage.  If  
you can detect it didn't, there are no requirements placed upon the  
semantics of the code.

> 3) Lifetime guarantees.  It would be really nice to be able to delete
> the store to X in:  " double *X = ...; *X = 4.0; delete X;" which is
> safe with 'free'.

Again, you can't inspect the value as there is no way to have those  
semantics without also then violating the required semantics of the  
deallocator and if you did that, then that standard places no  
requirements on the program, so net result you are free to omit the  
store.

> A lot of nice guarantees that we have with malloc/free aren't
> available with new/delete.  Also, since new/delete can be overridden
> at any time (as late as runtime with LD_PRELOAD and friends),

3 The program's definitions are used instead  of  the  default  versions
   supplied  by  the  implementation  (_dcl.fct.def_).   Such  
replacement
   occurs prior to program startup (_basic.def.odr_, _basic.start_).

So, the replacement is done before start, if later, there are no  
requirements.  And, the replacement has known semantics.



More information about the llvm-dev mailing list